[英]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.