未找到外部声明的模板专用函数
extern declared template specialized function not found
我正在尝试实现 json 序列化库的克隆 nlohmann::json 作为一种学习经验,但我在使用用户定义的界面时遇到了问题 (json <->用户类型)转换。
基本上我希望用户能够重载两个函数:to_json(json&, const Type&) 和 from_json(const json&, Type& ).然后库将使用重载决策在模板化 operator= 和一个参数构造函数中调用这些函数。
当我直接定义这些函数时,它工作正常,但是当我尝试为多种类型(在本例中为 class S)创建模板定义时,链接器找不到定义。
我已经尝试为模板化 class 的各个实例显式实例化函数,尽管我更愿意避免在最终产品中这样做。
我猜这与模板函数与自由函数的签名不同这一事实有关,但我不知道我能做些什么来让它工作。我错过了什么?我也无法在 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);
}
g(t)
调用中 g
的名称查找一旦找到 extern void g(const T&);
声明就会停止;它永远不会看到函数模板的声明。因此,编译器生成对名为 g
的常规非模板函数的调用,调用 const S<10>&
。但是你的程序中没有定义这样的函数 - 因此链接器错误。
我正在尝试实现 json 序列化库的克隆 nlohmann::json 作为一种学习经验,但我在使用用户定义的界面时遇到了问题 (json <->用户类型)转换。
基本上我希望用户能够重载两个函数:to_json(json&, const Type&) 和 from_json(const json&, Type& ).然后库将使用重载决策在模板化 operator= 和一个参数构造函数中调用这些函数。
当我直接定义这些函数时,它工作正常,但是当我尝试为多种类型(在本例中为 class S)创建模板定义时,链接器找不到定义。
我已经尝试为模板化 class 的各个实例显式实例化函数,尽管我更愿意避免在最终产品中这样做。
我猜这与模板函数与自由函数的签名不同这一事实有关,但我不知道我能做些什么来让它工作。我错过了什么?我也无法在 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);
}
g(t)
调用中 g
的名称查找一旦找到 extern void g(const T&);
声明就会停止;它永远不会看到函数模板的声明。因此,编译器生成对名为 g
的常规非模板函数的调用,调用 const S<10>&
。但是你的程序中没有定义这样的函数 - 因此链接器错误。