Consider the following code:
struct S {
struct type {};
type type;
};
int main() {
typename S::type t;
(void) t;
}
Apart for the fact that is far from being a good idea, I was experimenting after having read another question here on SO.
I found that the snippet above is compiled with no errors by GCC and it is rejected by clang 3.9 with the following error:
error: typename specifier refers to non-type member 'type' in 'S'
I suspect that clang is right in this case and GCC is wrong (actually, I'm opening an issue to the latter).
Is it the right conclusion or is that a valid use of typename
?
Note: I'm not asking how to solve it, I know how to do that. I'm asking only if this code is valid or not.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
[temp.res]/4:
The usual qualified name lookup is used to find the qualified-id even in the presence of
typename
.
That is, unlike the case with elaborated-type-specifiers, the name lookup in this case does not ignore non-type names.
[temp.res]/3:
If the qualified-id in a typename-specifier does not denote a type or a class template, the program is ill-formed.
So the program in question is ill-formed.
[temp.res]/4 also has an example for this:
struct A {
struct X { };
int X;
};
struct B {
struct X { };
};
template<class T> void f(T t) {
typename T::X x;
}
void foo() {
A a;
B b;
f(b); // OK: T::X refers to B::X
f(a); // error: T::X refers to the data member A::X not the struct A::X
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With