【发布时间】:2019-02-13 08:37:13
【问题描述】:
我在大型代码库中发生了潜在的 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_impl 和 foo_double_impl 的定义,而不是两个不同的 foo 定义。这是否解决了 ODR 违规问题?还是因为 foo 有两个不同的别名模板,所以 ODR 违规仍然存在?
【问题讨论】:
标签: c++ type-alias one-definition-rule