Adding typename causes program compilation to fail
So, I have this code:
#include "type_traits"
struct A{
int member;
};
struct B{
typedef A object;
typedef int member;
};
typedef std::integral_constant<B::member, B::object::*, &A::member> type;
But if I change the final line to:
typedef std::integral_constant<typename B::member, typename B::object::*, &A::member> type;
The program won't compile ....
Why typename
does adding a specifier cause the program to not compile? This is especially surprising to me because I thought I needed it in this case.
Note: Using gcc 5.1.0
source to share
You cannot add typename
wherever you want the type to be. You can only request and add typename
when you use a dependent type name.
The dependent name looks something like this:
template<typename T>
void foo() { (void)T::member(); }
Is it T::member
a named type or member function member
? The compiler will assume this is not the default type. If it is a type, you must specify typename
to disambiguate.
template<typename T>
void foo() { (void)typename T::member(); }
Now the compiler is told what it T::member
really is.
However, C ++ syntax only allows this in cases where the nature T::member
cannot be known. So when you are dealing with knowledge types such as your code, the compiler already knows that these members are types. There is nothing to discourage.
If you were to change the typedef with a template alias, it would require typename
, as you wrote:
template<typename C, typename D> // v----- Type of pointer to member?
using type = std::integral_constant<typename D::member D::object::*, &C::member>;
// Here, D::object::* don't need typename, ----^
// since only types are allowed here
source to share