简体   繁体   English

如果模板在不同类型的多个翻译单元中定义,则 ODR 冲突?

[英]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 bazbar的定义(构建时间长)。

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.为了避免包含依赖项barbaz ,向前声明它们就足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在GCC 6.3.0中违反ODR,且在两个单独的转换单元中定义了类型 - ODR violation in GCC 6.3.0 with types defined in two separate translation units 在不同的翻译单元中定义的类 - Class defined in different translation units 模板专业化违反ODR - ODR violation with template specializations 不同翻译单元中的多个定义 - Multiple definitions in different translation units 多个翻译单元中函数模板实例化的标识 - Identity of function template instantiation in multiple translation units 如果我不使用odr,可以在翻译单元中对它进行多个定义吗? - If I don't odr-use a variable, can I have multiple definitions of it across translation units? 使用不同优化级别编译的不同翻译单元中的模板实例化 - Template instantiation in different translation units compiled with different optimization levels 在名称空间中定义并在多个翻译单元中使用的变量的链接 - Linkage of a variable defined in a namepace and used in multiple translation units 在不同翻译单元中模板类静态变量的显式实例化 - explicit instantiation of static variable of a template class in different translation units 模板变量是否可以在多个翻译单元中使用并有效地合并? - Are template variables allowed within multiple translation units and effectively merged?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM