为什么在源文件中专门化模板不会导致错误?

时间:2019-09-24 15:58:59

标签: c++ templates g++ one-definition-rule

在回顾一些正在使用的代码时,我注意到一些我认为不应该编译的东西,但是令我惊讶的是。

头文件中定义了一个模板函数:

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对此进行了编译和链接,没有任何错误。

有人可以解释一下这是怎么回事吗?我是否丢失了某些内容,并且上面的代码实际上有效,还是仅是一种未定义的行为?

谢谢!

1 个答案:

答案 0 :(得分:0)

没有违反ODR。如果需要这样的专业化,则只有在第一次使用功能模板之前,才应声明该专业化并可见。