/* MyClass.h */
class MyClass
{
public:
template <typename T>
void Foo(const T &val);
};
/* MyClass.cpp */
#include <string>
#include <iostream>
#define EXPLICIT_INSTANTIATION_FOO(MyType) \
template void MyClass::Foo(const MyType &val)
EXPLICIT_INSTANTIATION_FOO(int);
EXPLICIT_INSTANTIATION_FOO(float);
EXPLICIT_INSTANTIATION_FOO(std::string);
template <typename T>
void MyClass::Foo(const T &val)
{
std::cout << "My Value: " << val << std::endl;
}
由于某些其他原因,我无法在头文件中定义Foo,然后我尝试显式实例化源文件中所需的所有类型。它在g ++ - 4.8上运行得很好。
然后,一旦我提交了代码,我发现Windows 10, x86_64, cl19
上的建筑失败了。这是一个未解决的符号错误,看起来我的实例化没有从对象中暴露出来。
但有趣的是,当我尝试通过上面的简单片段在我自己的Windows上重现此错误时。我发现它在我的vs2017上使用cl19 ...
公司和个人计算机之间会有数以千计的配置不同,但我只是不知道实例化在那里工作的原因是什么......任何想法都赞赏! :)
补充剂:
仅供参考,完整的代码在这里:
/* MyClass.h */
#pragma once
class MyClass
{
public:
MyClass();
~MyClass();
template <typename T>
void Foo(const T &val);
};
/* MyClass.cpp */
#include "MyClass.h"
#include <iostream>
#include <string>
#define EXPLICIT_INSTANTIATION_FOO(MyType) \
template void MyClass::Foo(const MyType &val)
EXPLICIT_INSTANTIATION_FOO(int);
EXPLICIT_INSTANTIATION_FOO(float);
EXPLICIT_INSTANTIATION_FOO(std::string);
MyClass::MyClass() {}
MyClass::~MyClass() {}
template <typename T>
void MyClass::Foo(const T &val)
{
std::cout << "My Value: " << val << std::endl;
}
/* main.cpp */
#include "MyClass.h"
#include <iostream>
#include <string>
int main()
{
std::string v = "hello";
MyClass cls;
cls.Foo(v);
std::cin.get();
return 0;
}
通过了msvc上的编译。
答案 0 :(得分:1)
将函数定义移至EXPLICIT_INSTANTIATION_FOO调用之前。这是一个永远不应该工作的东西,但是编译器,它们正慢慢地在它上面。如果你想让msvc拒绝它,请使用/ permissive-标志。
答案 1 :(得分:0)
谢谢大家,这个愚蠢的问题已经解决了。
原因是模板实例化不会从Windows上的模板定义继承dllexport属性。显然,它适用于我愚蠢的测试代码,因为它没有被编译为DLL :))