警告C4661:没有为显式模板实例化请求提供合适的定义

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警告!

这是正常的吗?

Ser*_*sta 7

您声明了模板的显式实例化.精细.但是你没有为构造函数提供定义:你只声明它.并且没有任何定义,模板也没有定义.

您必须在模板本身中提供定义:

...
public:
    Templated() {};  // empty but defined ctor
...
Run Code Online (Sandbox Code Playgroud)

或专业化:

Templated<int>::Templated() {
}
Run Code Online (Sandbox Code Playgroud)

从您的评论和编辑到问题,定义在另一个cpp文件中.问题是对于编译器,每个cpp文件都是不同的转换单元.换句话说,当编译第一个文件时,编译器不知道另一个文件.这就是你得到警告而不是错误的原因:警告意味着嘿程序员,你声明我想要一个Templated的专门实例化,但我找不到它的构造函数.希望你已经在另一个翻译单元中定义了它,因为如果你没有,你会在链接时遇到错误.正如您在其他文件中实际定义的那样,您可以放心地忽略该警告.

警告只表示发生了一些不常见的事情.通常,预期明确专业化的声明与其所有必需定义在同一翻译单元中.恕我直言,你应该坚持使用这种用法来避免警告,更重要的是,要有一个更易于维护的应用程序.