c++ - 为什么在源文件中特化模板不会导致错误?

标签 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 编译和链接它没有任何错误。

谁能给我解释一下这是怎么回事?我是否遗漏了什么,上面的代码实际上是有效的,或者这只是一种未定义的行为?

谢谢!

最佳答案

不存在违反 ODR 的情况。当需要这样的特化时,在第一次使用函数模板之前,只应声明和可见特化。

关于c++ - 为什么在源文件中特化模板不会导致错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58084175/

相关文章:

templates - 在 Golang 中结合使用模板 block 和模板函数

c++ - 测量移植到嵌入式平台的 C++ 的静态内存使用情况

c++ - g++ 在不使用 -Wconversion 的情况下将 double/float 转换为无符号整数时发出警告

Ruby eventmachine 编译错误

c++ - SSE/NEON查表优化

c++ - fnaf奇怪的表现

c++ - 如何从 C++ 程序内部重新启动 Linux?

c++ - CUDA 线程在全局内存中的私有(private)位置写入错误结果

c++ - 在模板类中通过引用传递

html - 在 Angular 2 中使用没有额外元素的 ngIf