2010-08-17 90 views
8

我做了以下程序我们什么时候需要一个.template构建

#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()是一个模板成员函数等等的.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构造之后编译?

+0

关于这个问题的完整和完整的答案可以在Comeau C++ Templates FAQ条目中找到[“什么是模板','.template'和':: template'语法?]] (http://www.comeaucomputing.com/techtalk/templates/#templateprefix)。 – 2010-08-17 03:52:56

+1

我被卡住了...§5.2.5/ 1说“后缀表达式后面跟着一个点或一个箭头 - >,**(可选)后跟关键字模板(14.8.1)**,然后跟着一个id -expression,是一个后缀表达式。“但是除了描述C++如何在没有关键字的情况下能够解析成员函数模板之外,14.8.1似乎是不相关的。此关键字在哪里指定? – Potatoswatter 2010-08-17 04:01:30

+0

@Patatoswatter:当然,关键字在§2.11表3中有详细说明。 ;-)(更严肃的说,这是一个很好的问题)。 – 2010-08-18 04:07:06

回答

14

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

例如考虑代码

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

的消除歧义时,template关键字要么variableconstant之前需要。案例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>; 
} 

如果关键字是在实际不清的情况(这是一种罕见的),才需要这将是一种不错的,但它使解析器多更容易编写,它可以防止这些问题令你惊讶。

对于standardese,见14.2/4:

当成员模板 专业化的名称后出现。或 - > 在一个后缀表达式,或之后 嵌套名称说明符在 合格-ID,和 后缀表达式或合格-ID 明确地依赖于 模板参数(14.6.2), 成员模板名称必须以关键字模板作为前缀 。否则, 名称被假定为命名为 非模板。

+0

第一个示例为+1:这是一个非常棒的代码片段,用于演示C++语法的上下文敏感性以及为什么需要这些关键字。 – 2010-08-18 04:45:57

0

第一示例编译并于2010年VS运行正常,我

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>) 

is bei ng叫。然而,这种功能不存在

即使在正常情况下“符”转换为“廉政”,这不成立好明确指定模板参数

相关问题