【发布时间】:2019-11-21 06:49:01
【问题描述】:
我有一个类模板的声明。假设此模板的特化从具有特定字符串 id 的数据库中保存和加载对象。我只需要将此模板用于特定类型,并将这些专业化放入不同的 cpp 文件中。
// TemplateInterface.h
template <typename T>
struct Foo
{
static void save(T const& v);
static T load();
};
假设我使用此代码保存 std::tuple 的值。
// TemplateInterface.cpp
template <>
struct __declspec(dllexport) Foo<Class1>
{
static void save(Class1 const& v)
{
MyDatabase::save("class1-id", v);
}
static Class1 load()
{
return MyDatabase::load("class1-id");
}
};
template <>
struct __declspec(dllexport) Foo<Class2>
{
static void save(Class2 const& v)
{
MyDatabase::save("class2-id", v);
}
static Class2 load()
{
return MyDatabase::load("class2-id");
}
};
如您所见,唯一的区别是字符串 ID。 (没有 __declspec(dllexport) 此代码不起作用。) 我发现,我可以在 single 文件中这样做:
// Source.cpp
template <typename T, typename Traits>
struct Helper
{
static void save(T const& v)
{
MyDatabase::save(Traits::getID(), v);
}
static T load()
{
return MyDatabase::load(Traits::getID());
}
};
template <typename T>
struct Foo
{
static void save(T const& v);
static T load();
};
struct Class1Traits
{
static std::string getID() { return "class1-id"; }
};
struct Class2Traits
{
static std::string getID() { return "class2-id"; }
};
template<>
struct Foo<Class1> : Helper<Class1, Class1Traits> {};
template<>
struct Foo<Class2> : Helper<Class2, Class2Traits> {};
但是当我在不同的文件中执行此操作时(TemplateInterface.h 中的声明和 TemplateInterface.cpp 中的专门化),我得到链接器错误:
error LNK2019: unresolved external symbol "public: static Class1__cdecl Foo<Class1>::load()" referenced in function _main
其他方法的错误相同。 添加 dllexport 并使用没有帮助。 你能帮帮我吗?
我知道的唯一解决方案是从模板规范中显式调用基类方法。但这是一个奇怪的解决方案。
【问题讨论】:
标签: c++ templates linker dllexport