15

我做了以下程序

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

上面的程序不能编译,因为它是一个模板成员函数,所以必须做beforedisplay()的限定。我对吗?.templatedisplay()

但是当我制作以下程序时

#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

4 回答 4

36

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

例如考虑代码

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

要么 要么T::variable必须T::constant是模板。该功能意味着不同的东西,具体取决于哪个是和哪个不是:

  1. 要么T::constant与 3 进行比较,布尔结果成为模板参数T::variable<>
  2. 或被T::constant<3>比较x->variable

为了消除歧义,在ortemplate之前需要关键字。情况1:variableconstant

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

案例二:

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

如果关键字仅在实际模棱两可的情况下(这种情况很少见)才需要,那就太好了,但它使解析器更容易编写,并且可以防止此类问题让您措手不及。

对于标准语,请参阅 14.2/4:

当成员模板专业化的名称出现在 . 或 -> 在后缀表达式中,或在限定标识符中的嵌套名称说明符之后,并且后缀表达式或限定标识符显式依赖于模板参数(14.6.2),成员模板名称必须是以关键字模板为前缀。否则,该名称被假定为命名非模板。

于 2010-08-17T23:56:28.827 回答
7

C++ 模板的 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',但这对于显式指定的模板参数并不适用

于 2010-08-17T05:08:14.333 回答
0

第一个示例在 VS 2010 中编译并运行良好。

于 2010-08-17T03:38:52.553 回答
0

该标准要求templateortypename关键字来消除依赖于模板上下文的事物的歧义

于 2010-08-17T03:36:13.693 回答