[英]ODR violation if template is defined in multiple translation units for different types?
I recently got to know that the following code is ill-formed, NDR:我最近知道以下代码格式不正确,NDR:
// foo.h
template <typename T>
void foo();
// foo_bar.cpp
template <>
void foo<bar>()
{ /* Implementation for bar */ }
// foo_baz.cpp
template <>
void foo<baz>()
{ /* Implementation for baz */ }
Due to the specializations not being declared in foo.h
.由于
foo.h
中未声明专业化。 The reason for not declaring them in foo.h
is to avoid #include
'ing the definitions of baz
and bar
(long build times).不在
foo.h
中声明它们的原因是为了避免#include
'ing baz
和bar
的定义(构建时间长)。
Explicit instantiations do not suffer from this problem - there's no need to declare them in the header.显式实例化不会遇到这个问题 - 无需在 header 中声明它们。 Therefore I thought about solving the above problem using explicit instantiation instead:
因此,我考虑使用显式实例化来解决上述问题:
// foo.h
template <typename T>
void foo();
// foo_bar.cpp
template <typename T>
void foo()
{ /* Implementation for bar */ }
template void foo<bar>();
// foo_baz.cpp
template <typename T>
void foo()
{ /* Implementation for baz */ }
template void foo<baz>();
In some way, it would be replacing specializations with explicit instantiations.在某种程度上,它将用显式实例化替换特化。 But then comes my question: is having two different implementations of the primary template
foo<T>
violating ODR, assuming they are instantiated for different types?但是接下来我的问题是:假设它们是针对不同类型实例化的,是否有两种不同的主模板
foo<T>
实现违反了 ODR?
Yes, this would technically still an ODR violation (presuming that the template definitions are not identical in both translation units).是的,这在技术上仍然会违反 ODR(假设两个翻译单元中的模板定义不相同)。
You'll probably get away with this, with most C++ compilers, but this is still a technical ODR violation -- the same template has a different definition in different translation units.对于大多数 C++ 编译器,您可能会侥幸逃脱,但这仍然是技术上的 ODR 违规——同一模板在不同的翻译单元中具有不同的定义。
If, on the other hand, you turn it into two template specializations (and not even define the template itself), then it would not be an ODR violation.另一方面,如果您将它变成两个模板特化(甚至没有定义模板本身),那么它就不会违反 ODR。 This is what specialized templates are for.
这就是专门模板的用途。
Based on the feedback from the comments, the answer is yes , this is an ODR violation.根据评论的反馈,答案是肯定的,这是违反 ODR 的。
To solve the original problem, a better solution is to declare the template specializations in the header.为了解决最初的问题,更好的解决方案是在 header 中声明模板特化。 To avoid including the dependencies
bar
and baz
, it's enough to forward-declare them.为了避免包含依赖项
bar
和baz
,向前声明它们就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.