【问题标题】:warning C4661:no suitable definition provided for explicit template instantiation request警告 C4661:没有为显式模板实例化请求提供合适的定义
【发布时间】:2017-05-24 13:53:32
【问题描述】:

我写了一个类模板并在不同的 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 警告!

这正常吗?

【问题讨论】:

  • 这能回答你的问题吗? stackoverflow.com/a/14138629/1450890
  • 你不需要在显式实例化中使用__declspec(dllexport)
  • 是的,我需要它...我导出我的模板,否则我链接问题!
  • 您的网络编译器链接显示了一个 Hello World 程序。 ....

标签: c++ c++11 templates visual-c++ visual-studio-2017


【解决方案1】:

您声明了模板的显式实例化。没关系,但是您没有为构造函数提供定义:您只声明它,模板没有定义,也没有实例化。

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

...
public:
    Templated() {};  // empty but defined ctor
...

或专业化:

Templated<int>::Templated() {
}

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

警告仅表示正在发生不常见的事情。通常,显式特化的声明应与其所有必需的定义位于同一翻译单元中。恕我直言,您应该坚持这种用法以避免警告,更重要的是,拥有更易于维护的应用程序。

【讨论】:

  • 当然,我忘了解释定义在另一个文件中,我已经编辑了我的问题!对不起!
猜你喜欢
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多