我的理解是,类类型的constexpr
全局变量几乎不可用,因为
constexpr
不允许前向声明对象。 static
会导致内联函数中的对象命名(是否使用ODR)违反ODR,因为相应的inline
定义将具有不同的含义。 extern constexpr
会违反ODR规则,这是在引用该对象时发生的。this
参数,也会对其进行引用。 extern constexpr
,即使未使用ODR,GCC和Clang都提示违反ODR(多个定义)。 这一切正确吗?有没有办法在不将其包装在
constexpr
函数中的情况下,使它具有全局类类型的inline
? 最佳答案
可以使用一些宏魔术和众所周知的额外间接级别,在 header 中安全地定义全局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; \
}
该宏在未命名的命名空间中提供了引用
到实现类模板中的对象实例。
header 中未命名空间中的每个对象都会生成
每个翻译单元中包含其 header 的唯一实例。
此外,为了防止违反ODR,重要的是对象
在例如功能模板的多个实例是相同的。
但是,对于引用而言,它们具有不同的身份并不重要;
只要它们在实现中引用相同的对象实例
类模板。
您可以将此宏包装在 header 中,并可以安全地将其包含在许多TU中。
有关更多详细信息,请参见Boost邮件列表上的以下讨论:
http://lists.boost.org/Archives/boost/2007/06/123380.php
关于c++ - constexpr全局类类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20370024/