2017-08-04 80 views
3

所以我有这样的代码:添加类型名称会导致程序失败的编译

#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; 

但是,如果我改变最后的行:

typedef std::integral_constant<typename B::member, typename B::object::*, &A::member> type; 

的程序将无法编译....

为什么添加typename说明符会导致程序无法编译?这对我来说尤其令人惊讶,因为我认为在这种情况下我需要它。

注: 使用GCC 5.1.0

回答

3

无处不在,你想指定类型不能添加typename。您只能使用依赖类型名称,并且需要添加typename

一个从属名称是这样的:

template<typename T> 
void foo() { (void)T::member(); } 

T::member一个类型,或命名member成员函数?编译器会默认它不是一个类型。如果是类型,则必须指定typename以消除歧义。

template<typename T> 
void foo() { (void)typename T::member(); } 

现在编译器被告知假设T::member确实是一个类型。

但是,C++语法只允许在不知道T::member的性质的情况下。因此,在处理知道类型时,如代码,编译器已经知道这些成员是类型的。没有什么可以消除歧义。

如果你要通过模板别名的typedef改变你,它需要typename,你写道:

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 
相关问题