[英]How to use make_tuple() in static constexpr class member?
我試圖在constexpr
使用make_tuple()
。 它適用於全球范圍。 但是它為static constexpr
類成員生成鏈接錯誤。
#include <iostream>
#include <tuple>
using namespace std;
class A
{
public:
static constexpr auto z = make_tuple(5, 3.0);
};
constexpr auto tp = make_tuple(6, 3.2);
int main()
{
cout << get<0>(tp) << " " << get<1>(tp) << endl; // OK
cout << get<0>(A::z) << " " << get<1>(A::z) << endl; // error: (.text+0x5a): undefined reference to `A::z'
// (.text+0x67): undefined reference to `A::z'
}
我在這里檢查了 make_tuple
本身不是c++11
的constexpr
。 我想在這種情況下這不是問題。 如果是這樣,它將生成一個編譯錯誤而不是鏈接錯誤。
我試圖像下面的答案所示的constexpr
婁一樣在類外定義constexpr
class A
{
public:
static constexpr tuple<int, double> z;
};
constexpr tuple<int, double> A::z = make_tuple(5, 3.0);
但是,它會產生幾個編譯錯誤。 根據使用靜態函數初始化靜態成員的constexpr的答案,這比較合理
在static constexpr
類成員中使用make_tuple
的正確方法是什么?
編譯器: g++ 4.8.4
和clang 3.4
-std=c++11
在C ++ static constexpr
如果使用ODR,則必須在某個位置定義 static constexpr
變量(使用ODR的意思是“以需要身份的方式使用”)。例如,使用真實的引用或指針。這里的ODR表示“一個定義規則”,而ODR所使用的意思是“在某種意義上使用,要求它只有一個定義”,我簡稱為“具有身份”。
constexpr tuple<int, double> A::z;
並定義了它的存在位置。 這必須在一個編譯單元中。
在C ++ 17中,添加了inline
變量,並且我相信constexpr
變量是隱式內聯的。 我不是C ++ 17專家,但是它沒有定義就可以在C ++ 1z模式下編譯和運行 ,因此我的解釋似乎至少是正確的一半。
( inline
變量,像inline
函數一樣,最終在編譯器需要的地方創建定義。 inline
函數通常是通過在每個對象文件中都有一個帶有特殊注釋的對象的定義來實現的,當有人獲取它的地址時,然后將重復項丟棄在鏈接時間,每個人都指最后一個站。我不知道inline
變量是否傾向於以相同的方式實現。)
如果要在C ++ 11中解決此問題而不必在帶有硬編碼模板參數的.cpp
文件中放入某些內容,請將z
更改為constexpr
函數 ,並在要使用它時調用它。
正如SergyA所提到的,ODR在這里被觸發是因為get
返回對該元組中某個字段的引用 ,並且該引用暗示該字段以及整個元組必須存在一個標識。
從理論上講,精心設計的由value返回的value_get
可以避免這種ODR使用,但這將取決於tuple
的實現,因為它反過來又不能調用get
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.