如何避免使用特质类违反ODR [英] How to avoid violating ODR with traits classes
问题描述
从生产库在线阅读代码时,我发现了这样的内容
On reading code online from production libraries I found something like this
Traits.hpp
template <typename Type>
class Traits {
template <typename T,
detail::EnableIfIsInstantiation<T, Type>* = nullptr>
static void foo(T& object) {
object.foo();
}
};
SpecialTraits.hpp
template <>
class Traits<Special> {
static void foo(Special& object) {
object.foo();
}
static void foo(Special&& object) {
object.special_foo();
}
};
如果库实例化在一个翻译单元中将Traits
用作Something
的类型而不包含SpecialTraits.hpp
的类型,然后实例化在另一翻译单元中使用特殊特性的类型,则将导致ODR违规.当这两个翻译单元链接在一起时,这会导致违反ODR.
This will cause an ODR violation if a library instantiates a type that uses Traits
for Something
in one translation unit without including SpecialTraits.hpp
and then instantiates a type that uses the specialized traits in another translation unit. This would cause an ODR violation when those two translation units are linked together.
为避免此问题,建议的方法是什么?我是否必须求助于在原始Traits.hpp
文件中包含所有专长?还有,如果不允许我编辑具有Special
定义的文件怎么办?
What is the suggested way to avoid this problem? Do I have to resort to including all the specializations in the original Traits.hpp
file? And what if I am not allowed to edit the file with the definition for Special
?
注意,请忽略以下事实:在&&
情况下,foo()
可能由Special
本身专门化了.我想不到一个更好的例子.
Note Please ignore the fact that foo()
could have been specialized by Special
itself in the &&
case. I could not think of a better example..
推荐答案
将专业名称放在"WidgetWrapper.hpp"中,而不是"Widget.hpp"中,并在各处都包含"WidgetWrapper.hpp".否则,请使用Boost提交错误报告,并期望它不会执行任何操作,因为确切的问题在15年前没有得到解决.
Put the specialization in "WidgetWrapper.hpp" instead of "Widget.hpp" and include "WidgetWrapper.hpp" everywhere. Otherwise, file a bug report with Boost and expect it to go nowhere since this exact problem was discussed 15 years ago with no resolution.
这篇关于如何避免使用特质类违反ODR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!