以下是个简单的模板类测试代码,模板类A中定义了模板函数hello,在模板函数test中调用A::hello
template_test.cpp

template <class T>
struct A{template<class I>void hello(){}template<class I>void hello2(I i){}
};
template <class T>
void test(A<T> & a)
{a.hello<int>();a.hello2(100);
}int main()
{A<int> a;test(a);
}

在Visual Studio 2015下可以正常编译通过,但在gcc 5.2.0下就不行,报错如下:

$ g++ template_test.cpp
template_test.cpp: In function 'void test(A<T>&)':
template_test.cpp:11:10: error: expected primary-expression before 'int'a.hello<int>();^
template_test.cpp:11:10: error: expected ';' before 'int'

解决这个问题的办法很简单修改A::hello函数的调用方式,增加template关键字申明hello为模板函数

template <class T>
void test(A<T> & a)
{a.template hello<int>();
}

为什么会这样?
添加 template 关键字的目的是消除语法歧义,告诉编译器hello是个模板成员。否则编译器会将后面的<视为比较运算符。

同样是模板成员函数,hello2因为调用时不需要指定显式模板参数,不加template关键字也可以被编译正确识别。

如下是C++标准中的说明(《14.2 Names of template specializations》):

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

以下是从C++标准文档(《Working Draft, Standard for Programming Language C++》 )摘录的14.2原文

那么为什么MSVC就不需要tempate关键字也能正常编译呢?我只能说在这个部分微软编译器更聪明些。

参考资料

《When do we need a .template construct》
《Confusing Template error (3)》

《模板和大于/小于符号的歧义》

《Working Draft, Standard for Programming Language C++》

c++模板:调用模板成员函数需不需要加template关键字?相关推荐

  1. C++模板学习02(类模板)(类模板语法、类模板与函数模板的区别、类模板中的成员函数创建时机、类模板对象做函数参数、类模板与继承、类模板成员函数类外实现、类模板分文件编写、类模板与友元)

    C++引用详情(引用的基本语法,注意事项,做函数的参数以及引用的本质,常量引用) 函数高级C++(函数的默认参数,函数的占位参数,函数重载的基本语法以及注意事项) C++类和对象-封装(属性和行为作为 ...

  2. c++成员函数的调用——常成员函数

    1.4-5 成员函数的选择调用一一常成员函数 (15 分) 类中的常对象选择调用常成员函数.语法要点: 如果将一个对象说明为常对象,则通过该常对象只能调用它的常成员函数,而不能调用其他成员函数.补充完 ...

  3. C++之常引用对象只能调用常成员函数、重载为成员函数和友元函数的区别

    近日写了一道题,遇到了新bug,使博主对C++的逻辑严密性有了更深的体会,特写此博客.本文标题是对两个bug的总结,即本文内容分为两部分. 题目如下: 设计一个CShape抽象类,类中包含纯虚函数   ...

  4. const对象只能调用const成员函数、不能调用非const成员函数;非const对象可以调用const成员函数

    引发原因: 由调用成员函数时隐式传入的当前对象的this指针引起. 1. 非const成员函数中的隐式参数:classA* this 2. const成员函数中的隐式参数:const classA* ...

  5. 一文带你入门C++,类与对象、6个默认成员函数、this指针以及static关键字。

    C++98关键字:63个 一.命名空间规则(namespace) 1.命名空间可以解决函数.全局变量名重复的问题,包在不同的命名空间里的重复函数,实际就是两个完全无关的函数. 2.命名空间允许续嵌套: ...

  6. 2021-03-10 模板扩展类调用模板基类成员函数

    侯捷书内 : 扩展模板类 内通过  this->  指模板基类的成员函数,或通过   基类名::  的方式调用 基类成员函数 侯捷书内说: 扩展模板类,找不到模板基类的成员函数 但是在vs201 ...

  7. static成员函数不能调用non-static成员函数

    1 一般类静态成员函数不能调用非静态成员函数 2 static成员函数可以调用构造函数吗? 答案是肯定的,由于static成员函数没有this指针,所以一般static成员函数是不能访问non-sta ...

  8. C++中空指针调用类成员函数的原理

    有下面的一个简单的类: class CNullPointCall { public:     static void Test1();     void Test2();     void Test3 ...

  9. php 调用模板,调用模板

    创建好模板后,我们还需要调用它们.否则他们一直被冷落,没准那天它们会疯.调用模版的方法只能在控制器中使用.PESCMS提供了 display() 和 layout两个方法. display参数说明备注 ...

最新文章

  1. powershell禁用计算机,PowerShell 因为在此系统中禁止执行脚本 解决方法
  2. python程序基础书写文本_Python基础手册4——文本结构
  3. 动态规划 HDU1231-------最大连续子序列
  4. VS配置本地IIS以域名访问
  5. TemplateBinding与Binding区别,以及WPF自定义控件开发的遭遇
  6. android gb2312 utf-8,不同编码页面之间用form传值出现乱码问题解决方案 utf-8 到 gb2312...
  7. BZOJ4448:[SCO2015]情报传递
  8. 【NLP】Stanford
  9. Linux系统升级硬盘后HOME分区扩容操作流程
  10. c# textbox和listbox多行显示
  11. 树莓派 调整分区大小
  12. c语言算法骑士,[算法]C语言实现 骑士旅游(递归)
  13. cad墙线打断lisp_CAD墙体如何打断,用tr命令不行,打散的话墙线会错位?
  14. 电力系统的常用仿真模块MATLAB/SIMULINK(2)
  15. 使用 SnakeYAML 操作 YAML 数据
  16. 物联网开发 无线433MHz安防报警系统 上
  17. 51单片机 - 红外遥控时钟
  18. java中文逗号替换成英文逗号_word如何将大量英文逗号批量替换为中文逗号?
  19. Web前端-html页面-01(锚点、表单、个人简历)
  20. mysql语句生成,SQL语句生成器

热门文章

  1. 基于SPRINGBOOT的尚筹网-创意产品众筹平台
  2. 基于Arduino的自动调速风扇
  3. android 电脑模拟点击,点击真理电脑版怎么下载 安卓模拟器电脑版下载地址
  4. labelme安装及使用
  5. 如何在Cisco ASA上查看和清除会话?
  6. [Voice communications] 声道的转换
  7. 模态指令和非模态指令
  8. 点一下详情系统挂了,CPU100%
  9. 关于python的分支结构、以下选项_关于 Python 的分支结构,以下选项中描述错误的是...
  10. 产品策划五:App界面设计风格