我们何时需要.template结构

Pra*_*rav 9 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);
}
Run Code Online (Sandbox Code Playgroud)

上面的程序没有编译,因为它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();
}
Run Code Online (Sandbox Code Playgroud)

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

Pot*_*ter 24

<标志是指"小于"和"开始模板参数." 为了区分这两个含义,解析器必须知道前面的标识符是否命名模板.

例如,考虑代码

template< class T >
void f( T &x ) {
    x->variable < T::constant < 3 >;
}
Run Code Online (Sandbox Code Playgroud)

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

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

要消除歧义,template关键字在其中之前variable或之前是必需的constant.情况1:

template< class T >
void f( T &x ) {
    x->template variable < T::constant < 3 >;
}
Run Code Online (Sandbox Code Playgroud)

案例2:

template< class T >
void f( T &x ) {
    x->variable < T::template constant < 3 >;
}
Run Code Online (Sandbox Code Playgroud)

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

对于标准,见14.2/4:

当成员模板专业化的名称出现之后.或 - >在postfix-expression中,或在qualified-id中的nested-name-specifier之后,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须是以关键字模板为前缀.否则,假定该名称命名非模板.


Chu*_*dad 7

C++模板的 5.1节详细解释了这个结构

以下功能有问题

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

} 
Run Code Online (Sandbox Code Playgroud)

这里T = char,U = int

myclass<char>::func<int>(myclass<char>) 
Run Code Online (Sandbox Code Playgroud)

被称为.但是这样的功能不存在

即使在正常情况下'char'可以转换为'int',但这对于明确指定的模板参数也没有好处