簡體   English   中英

用常量值初始化 std::array

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM