添加typename会导致程序编译失败

时间:2017-08-04 02:48:29

标签: c++ templates

所以我有这段代码:

#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

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确实是一种类型。

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

如果您要通过模板别名更改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