在回顾一些正在使用的代码时,我注意到一些我认为不应该编译的东西,但是令我惊讶的是。
头文件中定义了一个模板函数:
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对此进行了编译和链接,没有任何错误。
有人可以解释一下这是怎么回事吗?我是否丢失了某些内容,并且上面的代码实际上有效,还是仅是一种未定义的行为?
谢谢!
答案 0 :(得分:0)
没有违反ODR。如果需要这样的专业化,则只有在第一次使用功能模板之前,才应声明该专业化并可见。