完全专业化的模板功能

And*_*lli 1 c++ gcc templates template-instantiation

我有一个在头文件中声明的函数模板.该函数是一个归档程序,它应该支持通过项目实现的其他几种类型(类).我们的想法是拥有一个基本模板声明,然后每个类专门针对它自己的类型.

// Archiver.h
template <class T> void archive(Archiver & archiver, const T & obj);
Run Code Online (Sandbox Code Playgroud)

此方法没有实现.现在我创建一个类(比方说Header),我希望它可以存档.因此,我打算专门研究这种方法.这就是我现在拥有的:

// Header.h
extern template void archive(Archiver & archiver, const Header & obj);
Run Code Online (Sandbox Code Playgroud)

我声明该函数是extern因为我在.cpp文件中实现它

// Header.cpp
template <> void archive(Archiver & archiver, const Header & obj)
{
 // Code here
}
Run Code Online (Sandbox Code Playgroud)

这给了specialization after instantiation.我也尝试过其他组合:

  1. 直接在头文件中实现,通常建议用于模板:我得到"多重定义"
  2. 在头文件中没有声明的.cpp文件中的实现:我undefined reference从另一个编译单元调用该方法时得到

那么实现这个是正确的呢?

编辑:

最初我决定使用模板,因为反向过程,unarchiving.基本上我可以写,unarchive<Header>()而不是unarchive_header()似乎更合适.

我相信我还应该提到我正在使用Android Studio和Gradle构建系统编译它,这就是为什么我使用gcc而不是g ++.我还给了gcc以下编译器标志:

-std=gnu++11 -fexceptions -fpermissive -lstdc++
Run Code Online (Sandbox Code Playgroud)

-fpermissive 是一种绝望的行为.

Bar*_*rry 5

只是不要使用模板:

// Header.h
void archive(Archiver & archiver, const Header & obj);
Run Code Online (Sandbox Code Playgroud)

// Header.cpp
void archive(Archiver & archiver, const Header & obj)
{
 // Code here
}
Run Code Online (Sandbox Code Playgroud)

这样简单得多.只需进行一次非限定调用,archive()并确保在同一名称空间中声明此重载,Header 并让ADL发挥其魔力.