我正在尝试实现json序列化库nlohmann :: json的克隆作为学习体验,并且我在用户定义(json <->用户类型)转换的接口方面遇到麻烦。
基本上我希望用户能够重载两个函数:to_json(json&,const Type&)和from_json(const json&,Type&)。然后,库将使用重载分辨率在模板化的operator =和一个参数构造函数中调用这些函数。
当我只是直接定义这些函数时,效果很好,但是当我尝试为多种类型(在本示例中为S类)创建模板定义时,链接器找不到该定义。
我试图显式实例化模板化类的各个实例的功能,尽管我希望避免在最终产品中这样做。
我猜想这与以下事实有关:模板化函数与自由函数没有相同的签名,但是我不知道我能做些什么来使其工作。我想念什么?我也无法在Google上找到结果,所以它是记录的模式还是反模式?
谢谢。下面,我尝试通过一个简短的示例将问题最小化。
Class.hpp
#pragma once
#include <cstdio>
template<size_t i>
class S {
size_t n = i;
};
template<size_t i>
void g(const S<i>& s) {
printf("S<%u>\n", i);
}
Class.cpp
#include "Class.hpp"
template void g<10>(const S<10>&); // <-- Even with explicitly instanciation
void g(const bool& b) {
printf("%s\n", b ? "true" : "false");
}
main.cpp
#include "Class.hpp"
template<typename T>
void f(T t) {
extern void g(const T&);
g(t);
}
int main(int, char**) {
S<10> s;
//f(s); <-- linker error: void g(class S<10> const &) not found.
f(false);
}
答案 0 :(得分:3)
一旦找到g
声明,就会在g(t)
调用中对extern void g(const T&);
的名称查找停止;它永远不会看到功能模板的声明。因此,编译器使用g
生成对名为const S<10>&
的常规非模板函数的调用。但是您的程序中未定义此类功能-因此出现链接器错误。