En lecture de code en ligne des bibliothèques de production que je trouve quelque chose comme çaComment éviter de violer ODR avec des traits les classes
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();
}
};
Cela provoquera une violation ODR si une bibliothèque instancie un type qui utilise Traits
pour Something
dans une unité de traduction sans inclure SpecialTraits.hpp
, puis instancie un type qui utilise les traits spécialisés dans une autre unité de traduction. Cela entraînerait une violation ODR lorsque ces deux unités de traduction sont liées ensemble.
Quelle est la méthode suggérée pour éviter ce problème? Dois-je recourir à toutes les spécialisations du fichier original Traits.hpp
? Et si je ne suis pas autorisé à modifier le fichier avec la définition de Special
?
Remarque S'il vous plaît ignorer le fait que foo()
aurait pu être spécialisés par lui-même Special
dans le cas &&
. Je ne pouvais pas penser à un meilleur exemple ..
Mettez la spécialisation dans le même en-tête que la définition de 'Special'. –
@PeteBecker Bonne pensée! J'aurais dû inclure cela dans la question. mais que faire si vous n'y avez pas accès? Par exemple, disons qu'il s'agit d'une spécialisation pour un module 'boost' – Curious
Inclure l'en-tête avec la déclaration dans l'en-tête avec la spécialisation, et n'inclure que le dernier. –