我编写了一个类模板并在不同的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;
}
定义在一个单独的文件(.cpp)
中template<typename T>
Templated<T>::Templated() {}
template Templated<int>;
我的问题是我收到了警告,即使实例化被标记为已导出!
您可以在此处测试此代码:http://webcompiler.cloudapp.net/,它会生成C4661警告!
这是正常的吗?
答案 0 :(得分:6)
您声明了模板的显式实例化。精细。但是你没有提供构造函数的定义:你只能声明它。并且没有任何定义,模板也没有定义。
您必须在模板本身中提供定义:
...
public:
Templated() {}; // empty but defined ctor
...
或专业化:
Templated<int>::Templated() {
}
从您的评论和编辑到问题,该定义位于另一个cpp文件中。问题是对于编译器,每个cpp文件都是不同的翻译单元。换句话说,当编译第一个文件时,编译器不知道另一个文件。这就是为什么你得到警告而不是错误的原因:警告意味着嘿嘿程序员,你声明我想要一个Templated的专门实例化,但我找不到它的构造函数。希望您已在另一个翻译单元中定义它,因为如果您还没有在链接时收到错误。正如您在其他文件中实际定义的那样,您可以放心地忽略该警告。
警告只表示 uncommon 正在发生。通常,预期明确专业化的声明与其所有必需定义在同一翻译单元中。恕我直言,你应该坚持使用这种用法来避免警告,更重要的是,要有一个更易于维护的应用程序。