提问人:DragonDePlatino 提问时间:4/5/2021 更新时间:4/5/2021 访问量:158
命名空间中函数专用化的未定义引用
Undefined reference for function specialization in namespace
问:
我正在实现一个以 .对于要序列化的每种类型,定义一个接受存档和对象的非侵入式函数:boost::archive
// archive.hpp
#pragma once
namespace Archive {
template <class A, class T>
void serialize(A& a, T& value);
}
struct ArchiveOut {
void add(const char* key, int& value) {}
// ... Implementations for basic types ...
template <class T>
void add(const char* key, T& value) {
ArchiveOut archive;
Archive::serialize(archive, value);
}
};
// main.cpp
#include "archive.hpp"
struct Child {
int id;
};
struct Parent {
int id;
Child child;
};
template <class A>
void Archive::serialize(A& a, Parent& v) {
a.add("id", v.id);
a.add("child", v.child);
}
template <class A>
void Archive::serialize(A& a, Child& v) {
a.add("id", v.id);
}
int main() {
Parent parent;
ArchiveOut archive;
Archive::serialize(archive, parent);
}
目前,该系统适用于复杂的嵌套类型,但前提是它位于全局命名空间中。一旦它被移动到命名空间中,我就会收到一个链接器错误:serialize
Archive
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\DDP\AppData\Local\Temp\ccMWEvEu.o:test.cpp:(.text$_ZN10ArchiveOut3addI5ChildEEvPKcRT_[_ZN10ArchiveOut3addI5ChildEEvPKcRT_]+0x20): undefined reference to `void Archive::serialize<ArchiveOut, Child>(ArchiveOut&, Child&)
我知道我的专长有正确的签名,因为它们与助推器相匹配,但也许我最初的原型是错误的?我尝试过挖掘升压内部结构,但找不到初始原型的位置。我还检查了其他答案,所有这些答案都与与函数签名不匹配或未将其放置在正确的命名空间中的专业化有关。我能得到关于这种链接器行为的解释吗?serialize
答:
0赞
max66
4/5/2021
#1
您正在需要部分专业化的地方使用重载。
问题在于函数不能部分专用化。
建议:在部分专用结构中使用静态函数。
内容如下(注意:代码未测试)
// archive.hpp
namespace Archive {
template <typename A, typename T>
struct serial;
template <class A, class T>
void serialize(A& a, T& value)
{ serial<A, T>::func(a, value); }
}
// main.cpp
#include "archive.hpp"
// ...
namespace Archive {
template <class A>
struct serial<A, Parent>
{
static void func (A & a, Parent & v)
{
a.add("id", v.id);
a.add("child", v.child);
}
};
template <class A>
struct serial<A, Child>
{
static void func (A & a, Child & v)
{ a.add("id", v.id); }
};
}
评论
const unsigned int