我们何时需要.template结构

时间:2010-08-17 03:21:54

标签: c++ templates member-functions

我做了以下计划

#include <iostream>
#include <typeinfo>
template<class T>
struct Class
{
    template<class U>
    void display(){

        std::cout<<typeid(U).name()<<std::endl;
        return ;
    }

};


template<class T,class U>
void func(Class<T>k)
{
    k.display<U>(); 

}

int main()
{
    Class<int> d;
    func<int,double>(d);
}

上述程序无法编译,因为display()是模板成员函数,因此必须在.template之前完成display()的限定。我是对的吗?

但是当我制作以下节目时

#include <iostream>
#include <typeinfo>

template<typename T>
class myClass
{
    T dummy;
    /*******/
public:
    template<typename U>
    void func(myClass<U> obj);

};

template<typename T>
template<typename U>

void myClass<T>::func(myClass<U> obj)
{
    std::cout<<typeid(obj).name()<<std::endl;
}
template<class T,class U>
void func2(myClass<T>k)
{
    k.template func<U>(k); //even it does not compile

}
int main()
{
    myClass<char> d;
    func2<char,int>(d);
    std::cin.get();
}

为什么k.func<char>(k);即使在给出.template构造后也无法编译?

4 个答案:

答案 0 :(得分:19)

<符号表示“小于”和“开始模板参数”。为了区分这两个含义,解析器必须知道前面的标识符是否命名模板。

例如,考虑代码

template< class T >
void f( T &x ) {
    x->variable < T::constant < 3 >;
}

T::variableT::constant必须是模板。该函数意味着不同的东西取决于哪个,哪个不是:

  1. T::constant与3进行比较,布尔结果成为T::variable<>的模板参数
  2. T::constant<3>x->variable进行比较。
  3. 要消除歧义,templatevariable之前需要constant关键字。案例1:

    template< class T >
    void f( T &x ) {
        x->template variable < T::constant < 3 >;
    }
    

    案例2:

    template< class T >
    void f( T &x ) {
        x->variable < T::template constant < 3 >;
    }
    

    如果关键字仅在实际模糊的情况下需要(这种情况很少见)会很好,但它会使解析器更容易编写,并且可以防止这些问题让您感到意外。

    关于标准,见14.2 / 4:

      

    当成员模板的名称时   专业化之后出现。或 - &gt;   在后缀表达式中,或之后   a中的嵌套名称说明符   qual-id和   postfix-expression或qualified-id   明确取决于a   template-parameter(14.6.2),.   成员模板名称必须加前缀   通过关键字模板。否则   假定名称命名为   非模板。

答案 1 :(得分:7)

C++ Templates的第5.1节详细解释了这个结构

以下功能有问题

template<class T,class U> 
void func2(myClass<T> k) 
{ 
    k.template func<U>(k); //even it does not compile 

} 

这里T = char,U = int

myclass<char>::func<int>(myclass<char>) 
正在呼叫

。但是这样的功能不存在

即使在正常情况下'char'可以转换为'int',但这对于明确指定的模板参数不起作用

答案 2 :(得分:0)

该标准要求templatetypename个关键字disambiguate things that depend on the template context

答案 3 :(得分:0)

第一个例子在VS 2010中编译并运行正常。