CDZ*_*CDZ 4 c++ templates visual-c++ c++11 visual-studio-2017
我编写了一个类模板并在不同的DLL中使用它,所以希望隐藏实现的某些部分.
为此,我使用"模板实例化",但导出它,像这样,这里是头文件:
#include <iostream>
#include <exception>
using namespace std;
template<typename T>
class __declspec(dllexport) Templated
{
public:
Templated();
};
template __declspec(dllexport) Templated<int>;
int main()
{
cout << "Hello World" << endl;
}
Run Code Online (Sandbox Code Playgroud)
并且定义在一个单独的文件中(.cpp)
template<typename T>
Templated<T>::Templated() {}
template Templated<int>;
Run Code Online (Sandbox Code Playgroud)
我的问题是我收到了警告,即使实例化被标记为已导出!
您可以在此处测试此代码:http://webcompiler.cloudapp.net/,它将生成C4661警告!
这是正常的吗?
您声明了模板的显式实例化.精细.但是你没有为构造函数提供定义:你只声明它.并且没有任何定义,模板也没有定义.
您必须在模板本身中提供定义:
...
public:
Templated() {}; // empty but defined ctor
...
Run Code Online (Sandbox Code Playgroud)
或专业化:
Templated<int>::Templated() {
}
Run Code Online (Sandbox Code Playgroud)
从您的评论和编辑到问题,定义在另一个cpp文件中.问题是对于编译器,每个cpp文件都是不同的转换单元.换句话说,当编译第一个文件时,编译器不知道另一个文件.这就是你得到警告而不是错误的原因:警告意味着嘿程序员,你声明我想要一个Templated的专门实例化,但我找不到它的构造函数.希望你已经在另一个翻译单元中定义了它,因为如果你没有,你会在链接时遇到错误.正如您在其他文件中实际定义的那样,您可以放心地忽略该警告.
警告只表示发生了一些不常见的事情.通常,预期明确专业化的声明与其所有必需定义在同一翻译单元中.恕我直言,你应该坚持使用这种用法来避免警告,更重要的是,要有一个更易于维护的应用程序.