我们什么时候需要 .template 构造

发布于 2024-09-14 23:37:22 字数 1285 浏览 5 评论 0 原文

我编写了以下程序

#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() 是一个模板成员函数,因此在 display() 之前有 .template 的限定> 必须完成。我说得对吗?

但是当我编写以下程序时,

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

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

I made the following program

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

The above program doesn not compile because display() is a template member function so a qualification of .template before display() must be done. Am I right?

But when I made the following program

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

Why k.func<char>(k); does not compile even after giving a .template construct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

牵强ㄟ 2024-09-21 23:37:22

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

例如,考虑代码

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

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

  1. T::constant 与 3 进行比较,布尔结果成为 T::variable<>< /code>
  2. T::constant<3>x->variable 进行比较。

为了消除歧义,在 variableconstant 之前需要使用 template 关键字。情况 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:

当成员模板的名称
专业化出现在 .或->
在后缀表达式中,或之后
嵌套名称说明符
合格的 ID,以及
后缀表达式或限定 ID
明确依赖于
模板参数(14.6.2),
成员模板名称必须带有前缀
通过关键字模板。否则
假设名称为a
非模板。

The < symbol means both "less than" and "begin template arguments." To distinguish between these two meanings, the parser must know whether the preceding identifier names a template or not.

For example consider the code

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

Either T::variable or T::constant must be a template. The function means different things depending which is and which isn't:

  1. either T::constant gets compared to 3 and the Boolean result becomes a template argument to T::variable<>
  2. or T::constant<3> gets compared to x->variable.

The to disambiguate, the template keyword is required before either variable or constant. Case 1:

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

Case 2:

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

It would be kind of nice if the keyword were only required in actual ambiguous situations (which are kind of rare), but it makes the parser much easier to write and it prevents such problems from catching you by surprise.

For standardese, see 14.2/4:

When the name of a member template
specialization appears after . or ->
in a postfix-expression, or after
nested-name-specifier in a
qualified-id, and the
postfix-expression or qualified-id
explicitly depends on a
template-parameter (14.6.2), the
member template name must be prefixed
by the keyword template. Otherwise the
name is assumed to name a
non-template.

阪姬 2024-09-21 23:37:22

C++ 模板 的第 5.1 节详细解释了此构造

下面的函数有一个问题

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

} 

Here T = char 和 U = int

myclass<char>::func<int>(myclass<char>) 

正在被调用。然而这样的函数并不存在

即使在正常情况下“char”可以转换为“int”,但这对于显式指定的模板参数来说并不适用

Section 5.1 of C++ Templates explains this construct in detail

The below function has a problem

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

} 

Here T = char and U = int

myclass<char>::func<int>(myclass<char>) 

is being called. However such a function does not exist

Even though in normal circumstances 'char' is convertible to 'int', this does not hold good for explicitly specified template arguments

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文