我在头文件中声明了一个函数模板。该函数是一个归档程序,它应该支持通过项目实现的其他几种类型(类)。我们的想法是拥有一个基本模板声明,然后每个类专门针对它自己的类型。
// Archiver.h
template <class T> void archive(Archiver & archiver, const T & obj);
此方法没有实现。现在我创建一个类(比如Header
),我希望它可以存档。因此,我打算专门研究这种方法。这就是我现在所拥有的:
// Header.h
extern template void archive(Archiver & archiver, const Header & obj);
我将函数声明为extern
,因为我在.cpp文件中实现它
// Header.cpp
template <> void archive(Archiver & archiver, const Header & obj)
{
// Code here
}
这会给specialization after instantiation
。我也尝试过其他组合:
undefined reference
那么实现这个是正确的呢?
编辑:
最初我决定使用模板,因为反向过程,取消归档。基本上我可以写unarchive<Header>()
而不是unarchive_header()
,这似乎更合适。
我相信我还应该提到我使用Android Studio和Gradle构建系统来编译它,这就是我使用gcc而不是g ++的原因。我还给了gcc以下编译器标志:
-std=gnu++11 -fexceptions -fpermissive -lstdc++
-fpermissive
是一种绝望的行为。
答案 0 :(得分:5)
不要使用模板:
// Header.h
void archive(Archiver & archiver, const Header & obj);
和
// Header.cpp
void archive(Archiver & archiver, const Header & obj)
{
// Code here
}
这样简单得多。只需对archive()
进行无条件调用,并确保在与Header
相同的命名空间中声明此重载,并让ADL发挥其魔力。
答案 1 :(得分:2)
为什么要使用功能模板?
你说:
我们的想法是拥有一个基本模板声明,然后每个类专门针对它自己的类型。
如果函数模板没有默认实现,那么根本就没有它是没有意义的。你可以使用:
extern void archive(Archiver & archiver, const Header & obj);
当你需要它时。
如果必须使用功能模板
该行
extern template void archive(Archiver & archiver, const Header & obj);
不对。它必须是:
template <> void archive<Header>(Archiver & archiver, const Header & obj);
实现需要使用相同的签名。
template <> void archive<Header>(Archiver & archiver, const Header & obj)
{
}
更新,以回应OP的评论
我尝试了以下方法来模拟您的情况。
socc.h:
#pragma once
struct Archiver {};
template <class T> void archive(Archiver & archiver, const T & obj);
struct Header {};
template <> void archive<Header>(Archiver & archiver, const Header & obj);
socc.cc:
#include <iostream>
#include <string>
#include "socc.h"
int main()
{
Archiver ar;
Header obj;
archive(ar, obj);
}
socc-2.cc:
#include "socc.h"
template <> void archive<Header>(Archiver & archiver, const Header & obj)
{
}
构建命令:
g++ -std=c++11 -Wall socc.cc socc-2.cc -o socc
该计划已成功建立。
答案 2 :(得分:0)
在这种情况下,我认为,重载只是诀窍。你真的不需要这里的模板。
void archive(Archiver & archiver, const Header & obj);
void archive(Archiver & archiver, const Footer & obj);
void archive(Archiver & archiver, const Whatever & obj);