在检查工作中的一些代码时,我注意到一些我认为不应该编译的东西,但令我惊讶的是,它编译了。
头文件中定义了一个模板函数:
template <class T>
web::json::value get_key(const web::json::value &json, const utility::string_t &key) {
return json.has_field(key) ? json.at(key) : web::json::value(T());
}
在源文件方面具有特化:
template <>
web::json::value get_key<utility::string_t>(const web::json::value &json, const utility::string_t &key) {
return json.has_string_field(key) ? json.at(key) : web::json::value(utility::string_t());
}
编辑:头文件中未声明特化。
据我所知,这应该会导致编译器为 get_key<utility::string_t>
发出两个不同的定义。 ,一个用于源文件中的特化,一个用于实例化主模板,这违反了 ODR。然而,g++ 8.3.1 编译和链接它没有任何错误。
谁能给我解释一下这是怎么回事?我是否遗漏了什么,上面的代码实际上是有效的,或者这只是一种未定义的行为?
谢谢!
最佳答案
不存在违反 ODR 的情况。当需要这样的特化时,在第一次使用函数模板之前,只应声明和可见特化。
关于c++ - 为什么在源文件中特化模板不会导致错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58084175/