为啥尝试使用显式类型参数调用模板成员函数时会出错?

Posted

技术标签:

【中文标题】为啥尝试使用显式类型参数调用模板成员函数时会出错?【英文标题】:Why do I get an error trying to call a template member function with an explicit type parameter?为什么尝试使用显式类型参数调用模板成员函数时会出错? 【发布时间】:2011-06-23 23:36:33 【问题描述】:

我不明白,在我看来,对f 的调用是完全明确的,但它无法使用expected primary-expression before ‘int’ 进行编译。如果我注释掉调用f 的行,它编译得很好。

template<typename T>
struct A 
    template<typename S>
    void f()  
;

template<typename T>
struct B : A<T> 
    void g() 
        this->f<int>();
    
;

【问题讨论】:

我赞赏你不仅发现了这个邪恶的问题,而且在描述它时从未发誓。 【参考方案1】:

这是由于标准的一个非常模糊的规定,如果您有一个模板试图访问其类型取决于模板参数的对象中的模板函数,您必须在奇怪的方式:

this->template f<int>();

这类似于 typename 的奇怪之处,它带有依赖类型,除了应用于函数。特别是,如果您省略了 template 关键字,则在

this->f<int>()

(你想要的),和

((this->f) < int) > ()

这没有任何意义(因此你的错误)。此处使用关键字template 可以消除歧义并强制编译器识别它正在查看对模板化成员函数的完全有效调用,而不是一堆乱码。

希望这会有所帮助!

【讨论】:

我已经知道一些模板的语法怪异之处,但我以前从未听说过。 不仅答案很好,而且它还有一个额外的好处,它是由一个名为 templatetypedef 的用户提供的 :-) 他当然知道他在说什么...... Visual Studio 在某些模板功能上有些松懈。例如,它允许您在一些技术上需要的上下文中省略 typename,并自动从模板库中不应该这样做的地方导入名称。如果这是在 C++0x 中,而不仅仅是 VS 中的怪癖,我会感到惊讶。 @Pedro:它没有,Visual C++ 不兼容,因为它只在实例化时检查模板而不是两阶段查找。 @James:您失去了对明显错误的早期诊断(缺少;、名称拼写错误等),并且您在重载解决方案中遇到了麻烦(通常,只有在应该考虑使用模板,但是使用这个 VC++,您可以在考虑到模板作者可能没有预料到的之后声明的函数......我会说它肯定不会更好。然而,编译器发出这样一个愚蠢的警告是非常愚蠢的(与类型进行比较是没有意义的......),但是 gcc 从未因其用户友好性而闻名:/

以上是关于为啥尝试使用显式类型参数调用模板成员函数时会出错?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

将模板参数传递给调用成员函数的函数

为啥成员函数不能用作模板参数?

在成员变量中使用模板类作为模板模板参数时出错

java里为啥主函数前面要加static修饰

为啥为非泛型方法或构造函数提供显式类型参数会编译?