4

我有一个类模板,它恰好与某些类的成员函数模板同名。现在,另一个函数模板被实例化为具有相关成员函数模板的类之一。要在这个函数模板中调用成员函数模板我需要使用template关键字,我理解这一点并且对此没有问题。但是,我需要使用范围解析运算符(我刚刚发现这就是所谓的)::来指定我的意思是类的成员函数模板而不是类模板,我不明白为什么。

这是很多模板化的东西,所以让我举个例子:

    //class with same name as member function below.
    //must be class template or error doesn't show up.
    //also no error if this is a function template instead of class
    template <class T>
    struct f
    {
    };

    struct Base
    {
        //function with same name as struct above,
        //no error if this is not templated
        template <int N>
        void f(){}
    };

    //template function that will be instantiated with T=Base.
    //no error if this is not templated
    template <class T>
    void g(T t)
    {
        //I understand why template keyword is needed here,
        //but not why T:: is needed
        t.T::template f<0>();
        //t.template f<0>(); gives error.
    }

有问题的错误是(来自 g++-4.7)

    error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct f’
    error:   expected a type, got ‘0’

似乎编译器f<0>()在注释掉的行(没有范围解析运算符)上解析为试图实例化 type 的对象struct f<0>。我不知道它为什么这样做,我认为它应该能够从t.template我试图访问成员函数模板中看到。

我想了解这里发生了什么,为什么T::在这种情况下需要,除了安抚编译器?

在 MSVC 和 Clang 下似乎没有问题,所以它似乎是一个 g++ 特定的问题。

4

2 回答 2

1

我认为这与两阶段查找有关。尤其是史蒂夫·杰索普斯(Steve Jessops)在答案中的注释很重要。

于 2013-05-15T08:20:01.757 回答
0

这可能有效

template <class T>
void g(T t)
{
    t.T::template f<0>(); 
}
于 2013-05-15T04:28:26.997 回答