[英]Initializing a std::array with a constant value
我需要用常量值初始化std::array
的所有元素,就像可以用std::vector
完成一樣。
#include <vector>
#include <array>
int main()
{
std::vector<int> v(10, 7); // OK
std::array<int, 10> a(7); // does not compile, pretty frustrating
}
有沒有辦法優雅地做到這一點?
現在我正在使用這個:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
但我想避免使用顯式代碼進行初始化。
使用std::index_sequence
,您可以這樣做:
namespace detail
{
template <typename T, std::size_t ... Is>
constexpr std::array<T, sizeof...(Is)>
create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}
template <std::size_t N, typename T>
constexpr std::array<T, N> create_array(const T& value)
{
return detail::create_array(value, std::make_index_sequence<N>());
}
隨着使用
auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>
與std::fill
解決方案相反,它處理非默認可構造類型。
唉,不是; std::array
支持聚合初始化,但這還不夠。
幸運的是,您可以使用std::fill
,甚至std::array<T,N>::fill
,從 C++20 開始,它是優雅的,因為后者變成了constexpr
。
參考: https ://en.cppreference.com/w/cpp/container/array/fill
您可以執行以下操作
std::array<int, 10> a;
a.fill(2/*or any other value*/);
或者使用算法頭文件中的std::fill
。 包括算法頭文件使用
#include <algorithm>
從 C++17 開始,您可以編寫一個 constexpr 函數來有效地設置數組,因為元素訪問器現在是 constexpr。 此方法也適用於設置初始值的各種其他方案:
#include <array>
template<typename T, size_t N>
constexpr auto make_array(T value) -> std::array<T, N>
{
std::array<T, N> a{};
for (auto& x : a)
x = value;
return a;
}
int main()
{
auto arr = make_array<int, 10>(7);
}
std::array
類型是支持列表初始化的聚合:
std::array<int, 10> a{2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
它還支持聚合初始化:
std::array<int, 10> a = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
這對於長數組來說既不方便又容易出錯,最好使用 Jarod42 之類的解決方案。
如前所述, fill
解決方案不適用於非默認可構造類型。 index_sequence
解決方案是正確的,但有點冗長。
給定一個值t
(任何類型)和一個編譯常數N
,以下在一行中計算出所需的解決方案。
std::apply([&](auto... e) {return std::array{(e, t)...};}, std::array<int, N>{});
在此處查看完整代碼: https ://godbolt.org/z/jcq4fqMsE
此解決方案可應用於 C++17,並對早期版本進行一些修改。
這可以通過創建一個返回所需數組的 function 模板來相當容易地完成,如下所示。 甚至可以在編譯時初始化數組。(請參閱答案末尾給出的 c++17 示例演示)。
template<std::size_t N> std::array<int, N> make_array(int val)
{
std::array<int, N> tempArray{}; //create local array
for(int &elem:tempArray) //populate it
{
elem = val;
}
return tempArray; //return it
}
int main()
{
//---------------------V-------->number of elements
auto arr = make_array<10>(7);
//------------------------^---->value of element to be initialized with
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints all 7
}
}
另請注意,甚至可以在編譯時使用 C++17 執行此操作。演示 C++17
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.