- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个类模板声明。假设此模板的特化从具有特定字符串 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),此代码将不起作用。)我想通了,我可以在一个单个文件中这样做:
// 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 和使用没有帮助。你能帮帮我吗?
我知道的唯一解决方案是从模板规范中显式调用基类方法。但这是一个奇怪的解决方案。
最佳答案
模板实例化与模板特化不同。
例如,拿这段代码,告诉我会发生什么:
// TemplateInterface.h
template <typename T>
struct Foo
{
static T load();
};
int main() {
int foo = Foo<int>::load();
}
然后,将其添加到一个单独的、已编译的 cpp 中:
template <>
struct Foo<int>
{
static int load_special()
{
return 0;
}
};
如您所见,根据特化,没有Foo<int>::load()
, 但只有 Foo<int>::load_special()
.
您的代码实际上违反了 ODR。
如果您想要专门化您的模板并希望将专门化隐藏到它自己的 cpp 文件中,您必须告诉编译器您的类型有专门化以防止它实例化主模板。
这是通过转发声明您的专业来完成的:
template<>
struct Foo<int>; // specialization elsewhere!
关于c++ - 单独的类模板声明和特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56991085/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!