Avoiding ODR Violation Using Feature Classes

When 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(); } }; 

This will lead to ODR violation if the library creates an instance of the Traits type for Something in one translation unit without including SpecialTraits.hpp , and then creates an instance of a type that uses specialized features in another translation unit. This can lead to ODR violation when these two translation units are connected.

What is the suggested way to avoid this problem? Should I resort to including all specializations in the Traits.hpp source file? And what if I am not allowed to edit the definition file for Special ?

Note Please ignore the fact that foo() could have been specialized by Special itself in the && case. I could not come up with a better example.

+5
source share
1 answer

Put the specialization in "WidgetWrapper.hpp" instead of "Widget.hpp" and include "WidgetWrapper.hpp" everywhere. Otherwise, write a bug report with Boost and expect it to disappear, as this exact issue was discussed 15 years ago without permission.

+3
source

Source: https://habr.com/ru/post/1268735/


All Articles