[英]constexpr global of class type
我的理解是,类型的constexpr
全局变量几乎无法使用,因为
必须在每个TU中定义这样的对象,因为constexpr
不允许对象的前向声明。
默认链接为static
会导致在内联函数中命名对象(ODR使用与否)以违反ODR,因为相应的inline
定义具有不同的含义。
如果对象是ODR使用的,则每个TU具有一个定义的extern constexpr
声明将违反ODR规则,这在对其进行引用时会发生。
this
参数,即使它已被成员函数使用。 extern constexpr
即使没有使用ODR,GCC和Clang都会抱怨ODR违规(多个定义)。 这都是正确的吗? 是否有任何方法可以在没有将其包含constexpr
inline
函数中的情况下拥有类型的constexpr
全局?
全局constexpr变量可以使用一些宏魔法和众所周知的额外间接级别在头文件中安全地定义ODR
#define PP_GLOBAL_CONSTEXPR_VARIABLE(type, var, value) \
namespace var##detail { \
template<class = void> \
struct wrapper \
{ \
static constexpr type var = value; \
}; \
template<class T> \
constexpr type wrapper<T>::var; \
} \
namespace { \
auto const& var = var##detail::wrapper<>::var; \
}
宏在未命名的命名空间内向实现类模板中的对象实例提供引用。
标头内未命名的命名空间中的每个对象在包含其标头的每个转换单元中生成唯一的实例。 此外,为了防止ODR违规,重要的是例如功能模板的多个实例中的对象是相同的。
但是,对于参考文献而言,它们具有不同的身份并不重要; 只要它们在实现类模板中引用相同的对象实例。
您可以将此宏包装在标头中,并将其安全地包含在许多TU中而不会出现问题。
有关详细信息,请参阅Boost邮件列表中的以下讨论: http : //lists.boost.org/Archives/boost/2007/06/123380.php
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.