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 will not compile....
Why does adding the typename 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
You cannot add typename everywhere you want to specify a type. You can only, and require to add typename when you use a dependent type name.
A dependent name is something like this:
template<typename T>
void foo() { (void)T::member(); }
Is T::member a type, or a member function named member? The compiler will assume it's not a type by default. 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 to assume that T::member is indeed a type.
However, the C++ syntax only allow it in cases that the nature of T::member cannot be known. So when dealing with know types, like your code, the compiler already know that these members are types. There's nothing to desambiguate.
If you were to change you typedef by 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
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