У меня есть потенциальное нарушение ODR в большой базе кода.Это шаблон класса, который переключает поведение на основе #ifdef в разных библиотеках, но конфликтующие библиотеки, вероятно, используют разные экземпляры шаблона.В качестве упрощенного примера:
// foo.h
#ifdef USE_DOUBLE
template <typename T>
struct foo { T* value; double x; };
#else
template <typename T>
struct foo { T* value; };
#endif
struct c;
// a_lib.cpp
#include "foo.h"
struct a { foo<a> m_a; };
struct a_helper { foo<c> m_c; };
// b_lib.cpp
#define USE_DOUBLE
struct b { foo<b> b; };
struct b_helper { foo<c> m_c; };
- Я предполагаю, что
foo<a>
и foo<b>
не имеют нарушения ODR, верно? - Но что разные определенияиз
foo<c>
, привнесенных a_helper
и b_helper
, просто невероятно схематично, верно?
Подвох в том, что у меня есть это в огромном проекте.Кроме того, вероятно (но не уверен), что у меня есть только эквивалент не перекрывающихся a
и b
, а не проблемных a_helper
и b_helper
.Однако я не совсем уверен.
Мне интересно, смогу ли я избежать этой проблемы, изменив foo на шаблон псевдонима:
template <typename T>
struct foo_double_impl { T* value; double x; };
template <typename T>
struct foo_impl { T* value; };
#ifdef USE_DOUBLE
template <typename T>
using foo = foo_double_impl<T>;
#else
template <typename T>
using foo = foo_impl<T>;
#endif
Теперь вместо двух разных определений foo у нас теперь есть определения foo_impl и foo_double_impl.Разрешает ли это нарушение ODR?Или нарушение ODR сохраняется, потому что есть два разных шаблона псевдонима foo?