c++ - 为什么在 C++ 中允许重新声明模板成员函数?

标签 c++

class test{
 public:
 int call();
};

int test::call();

int main(){return 0;}
上面的不会编译,出现这个错误:
error: declaration of 'int test::call()' outside of class is not definition 
但是,如果这样使用模板,则允许使用相同的代码:
class test{
 public:
 template<class T>
 int call();
};

template int test::call<int>(); // what's the point of this line?

template <class T>
int test::call(){
  T in = 5;
  return in;
}

int main(){
 test t;
 
 return 0;
}
我有两个问题:
1-重新声明有什么意义?我在其他项目中看到过类似的代码。
2- 为什么它可以编译而我的第一个代码片段却不能?

最佳答案

这不是声明,而是定义。这称为 explicit template instantiation of a function template .
这会强制编译器实例化 int你的情况下的版本。您还可以为多种类型添加显式实例化:

class test{
 public:
 template<class T>
 int call() { return 0; }
};

template int test::call<int>();
template int test::call<float>();
通过控制实例化发生的时间来加快编译速度或控制实例化要求的可见性非常有用。这通常与 extern template 一起使用特征:
// ------------------
// ----- test.h -----
// ------------------
class test{
 public:
 template<class T>
 int call();
};

// Here, we tell the compiler that the instantiation exists somewhere
// That somewhere may not visible, so the compiler won't try to instantiate it
extern template int test::call<int>();
extern template int test::call<float>();


// ------------------
// ---- test.cpp ----
// ------------------

#include "test.h"

// define the template in the cpp only
template <class T>
int test::call(){
  T in = 5;
  return in;
}

// provide definitions for the instantiations:
template int test::call<int>();
template int test::call<float>();

关于c++ - 为什么在 C++ 中允许重新声明模板成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68461857/

相关文章:

c++ - 我正在创建一个 C++ 程序,其中用户有 2 次尝试密码用户名组合的尝试。如果他们不能得到它,他们的程序就会停止

c++ - C++ 什么时候调用作为类成员的对象的构造函数?

c++ - SFINAE成员函数存在性测试问题

c++ - 如何正确使用 peek(),或者是否有更好的解决方案来读取文本文件?

c++ - MoltenVK(用于 Vulkan)在 OS X v. 10.13.3 (17D102) 上构建失败 | Xcode 版本 9.2 (9C40b)

c++ - 使用 boost::bind 输出作为数组下标

c++ - PFYvv 代表什么? (不是 PFvv!)

c++ - 使用 Qt 读取、写入和搜索文本文件

c++ - 你如何在 C++ 中返回一个二维数组?

c++ - 为什么我无法将字符串添加到组合框?