分配具有相同值的多维std :: array的简单方法?

时间:2016-12-02 14:52:59

标签: c++ arrays c++11

我正在寻找一种简单的方法来分配具有相同值的多维数组?例如

using namespace std;

array<array<array<int, 2>, 3>, 4> a;

并希望a[:][:][:]的所有元素都是10.我不想使用3个循环。一个循环很好。

1 个答案:

答案 0 :(得分:4)

简单的方法是

for (auto& a1:a) for (auto& a2:a1) for (auto& a3:a2)
    a3 = 10;

略微更直接,但不那么通用:

a = {{ 
    {{ {{ 10, 10 }}, {{ 10, 10 }}, {{ 10, 10 }} }},
    {{ {{ 10, 10 }}, {{ 10, 10 }}, {{ 10, 10 }} }},
    {{ {{ 10, 10 }}, {{ 10, 10 }}, {{ 10, 10 }} }},
    {{ {{ 10, 10 }}, {{ 10, 10 }}, {{ 10, 10 }} }},
}};

最后,由于std::array<>保证了连续存储,你可以“作弊”并做

std::fill(
    &*a.front().front().begin(),
    &*a.back().back().end(),
    10);

有趣的是,clang generates identical assembly 适用于所有三种方法:

enter image description here

T

n维数组进行推广
#include <array>
#include <algorithm>

namespace detail {
    struct nested_range_helper {
        template <typename T>           static auto array_inner_begin(T& o)                { return std::addressof(o); } 
        template <typename T, size_t N> static auto array_inner_begin(std::array<T, N>& o) { return array_inner_begin(o.front()); }

        template <typename T>           static auto array_inner_end  (T& o)                { return std::addressof(o) + 1; } 
        template <typename T, size_t N> static auto array_inner_end  (std::array<T, N>& o) { return array_inner_end(o.back()); }
    };
}

template <typename T> 
auto innermost_begin(T& v) { return detail::nested_range_helper::array_inner_begin(v); }
template <typename T> 
auto innermost_end(T& v) { return detail::nested_range_helper::array_inner_end(v); }

template <typename T, typename V> void method3(T& a, V v = V{}) {
    std::fill(innermost_begin(a), innermost_end(a), v);
}

int main() {
    std::array<std::array<std::array<int, 2>, 3>, 4> a;
    std::array<std::array<double, 7>, 21> b;

    method3(a, 10);
    method3(b, 3.14);
}

使用clang时仍然会发出相同的优化组件:https://godbolt.org/g/d1kj3m