C++ GCC模板:预期为»;(«;在»;>;«;令牌之前)

C++ GCC模板:预期为»;(«;在»;>;«;令牌之前),c++,templates,gcc,C++,Templates,Gcc,我不明白为什么下面的代码不能编译: template< typename TypeArg > class Data { public: struct Selector1 { }; template< typename Selector > void foo() { } }; template< typename TypeArg > class Test { public: void test(

我不明白为什么下面的代码不能编译:

template< typename TypeArg >
class Data
{
public:
    struct Selector1
    {
    };

    template< typename Selector >
    void foo()
    {
    }
};

template< typename TypeArg >
class Test
{
public:
    void test();
};


template< typename TypeArg >
void Test< TypeArg >::test()
{
    Data< TypeArg > data;
    data.foo< typename Data< TypeArg >::Selector1 >();
}
模板
类数据
{
公众:
结构选择器1
{
};
模板
void foo()
{
}
};
模板
课堂测试
{
公众:
无效试验();
};
模板
无效测试::测试()
{
数据数据;
data.foo::选择器1>();
}
我已经用GCC 4.6和GCC 4.9对其进行了测试。两者都给出了相同的错误:

test.cpp:在成员函数»void test::test()«: test.cpp:28:51:错误:预期»(«之前»>«令牌 test.cpp:28:53:错误:在»)«标记之前应为主表达式


有人能告诉我编译代码需要做什么吗?

因为
数据的类型是依赖的,所以
数据的性质是未知的,需要消除歧义:

data.template foo<typename Data< TypeArg >::Selector1>();
//   ^^^^^^^^
data.template foo::Selector1>();
//   ^^^^^^^^

由于
数据的类型是依赖的,因此
data.foo的性质未知,需要消除歧义:

data.template foo<typename Data< TypeArg >::Selector1>();
//   ^^^^^^^^
data.template foo::Selector1>();
//   ^^^^^^^^

谢谢,这很有效。但是为什么需要这样做呢?对于编译器来说,
data
的类型是依赖的,
data.foo
是未知的,这不是很明显吗?@v0id:当然,但不明显的是你想要的
foo
是什么:一个值、一个类型或一个模板。因为这是未知的。所以你需要指定。换句话说,是
@T.C.它是一个模板参数列表。@theV0ID:我们知道你知道。但是问题是创建一个具有明确含义的语言构造。这是通过要求对依赖名进行显式消歧来完成的。谢谢,这很有效。但是为什么需要这样做?编译器不清楚
数据的类型是依赖的,并且
数据。foo
是未知的吗?@theV0ID:当然,但不明显的是您希望
foo
是什么:一个值、一个类型或一个模板。因为它是未知的。所以您需要指定。换句话说,
@t.C。它是一个模板参数列表。@theV0ID:我们知道您知道这一点。但问题是创建一个l具有明确含义的语言构造。这是通过要求对依赖名称进行显式消歧来实现的。