我想寫一些代碼如下:
using int_list_t = std::initializer_list<int>;
struct ThreeDimensionalBox {
static constexpr int_list_t kDims = {1, 2, 3};
};
struct FourDimensionalBox {
static constexpr int_list_t kDims = {4, 5, 6, 7};
};
template<typename Box1, typename Box2>
struct CombinedBox {
static constexpr int_list_t kDims = Box1::kDims Box2::kDims; // error
};
using SevenDimensionalBox = CombinedBox<ThreeDimensionalBox, FourDimensionalBox>;
有什么方法可以修復 的實施CombinedBox,以便SevenDimensionalBox::kDims有效地系結到{1, 2, 3, 4, 5, 6, 7}?
我知道我可以用std::initializer_list<int>帶有可變 int 模板引數串列的自定義模板類替換,并通過標準元編程遞回技術有效地實作串聯。我只是想知道是否存在僅使用std::initializer_list.
uj5u.com熱心網友回復:
std::initializer_list只能初始化為空,用大括號括起來的元素串列,或者通過復制。
然而,即使使用復制構造,std::initializer_list參考的實際陣列的生命周期也取決于由大括號括起來的元素串列初始化的原始std::initializer_list物件的生命周期。換句話說,復制std::initializer_list不會復制陣列或延長其生命周期。
因此不可能連接std::initializer_lists。它們并不意味著用作容器。Astd::initializer_list應該主要僅用作函式引數,作為一種輕量級方式,將未指定大小的大括號括起來的元素串列傳遞給函式,以便函式進一步處理元素。
你可能想要std::array。像這樣的東西(需要 C 17,但不是 C 20):
struct ThreeDimensionalBox {
static constexpr auto kDims = std::array{1, 2, 3};
};
struct FourDimensionalBox {
static constexpr auto kDims = std::array{4, 5, 6, 7};
};
template<typename T, std::size_t N, std::size_t M>
constexpr auto concat_arrays(const std::array<T, N>& a, const std::array<T, M>& b) {
// assumes `T` is default-constructible
std::array<T, N M> r;
std::copy(std::begin(a), std::end(a), std::begin(r));
std::copy(std::begin(b), std::end(b), std::begin(r) N);
return r;
}
template<typename Box1, typename Box2>
struct CombinedBox {
static constexpr auto kDims = concat_arrays(Box1::kDims, Box2::kDims);
};
using SevenDimensionalBox = CombinedBox<ThreeDimensionalBox, FourDimensionalBox>;
uj5u.com熱心網友回復:
std::initializer_list完全只有一個目的:成為初始化物件的工具,在 braced-init-list(中的內容{})用于初始化該物件的范圍內。這種型別的一切都是為此目的而構建的,它有一堆防火墻來防止你用它做任何其他事情。
其中最重要的是它initializer_list實際上并不存盤任何東西;它參考存盤在別處的值陣列(即{}創建它的參考)。因為它不存盤陣列,而且它們只是從{}語法結構構建的,所以你不能給它們一個陣列來參考。他們只能initializer_list通過復制從現有物件中獲取一個陣列,并且只能從 a{}或現有物件中獲取一個陣列,而現有物件只能initializer_list從中獲取一個......好吧,你明白了。
如果你需要做編譯時的陣列操作,std::array是一個更好的工具。如果你想連接兩個大括號初始化串列并使用結果來初始化某個物件......你不能那樣做。
不要嘗試initializer_list用作快速而骯臟的陣列型別。僅將其用于初始化物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/534077.html
標籤:C 模板元编程初始化列表
上一篇:為什么類成員的型別推導失敗?
下一篇:概念中的隱式轉換
