How to assign an array with move in one line?

时间:2016-12-02 05:12:52

标签: c++ arrays c++11 move-semantics

For example

using namespace std;

array<vector<int>, 3> a;
vector<int> v0, v1, v2;

// assign with move
a[0] = move(v0);
a[1] = move(v1);
a[2] = move(v2);

How to use one line to implement the assignment like a = {v0, v1, v2}?

3 个答案:

答案 0 :(得分:0)

如果您要初始化新的std::arrayarray<vector<int>, 3> a = { move(v0), move(v1), move(v2) }将一直有效,否则构建一个临时std::array,然后在<algorithm>中使用std::move:< / p>

array<unique_ptr<int>, 3> temp_arr = { move(a), move(b), move(c) };
move( begin(temp_arr), end(temp_arr), begin(arr) );

答案 1 :(得分:0)

@ user1899020:您可以参考此What is std::move(), and when should it be used?

请注意“移动语义是对程序员透明地执行的。只移动一个强制转换,将值从一个点传递到另一个不再使用原始左值的值。”

所以在下面的代码中:

a= {move(v0), move(v1), move(v2)};

for(int i=0; i <3; i++)
{
    // Iterate and print values of vector
    for(int n : a[i]) {
        std::cout << n << '\n';
    }
}

**//Code will NOT enter below for loop**
for (std::vector<int>::const_iterator  j= v0.begin(); j != v0.end(); j++)
    std::cout << *j << ' ';  

因此,如果您想使用保留原始向量中的值,

  1. 一种方法是:a = {v0, v1, v2};
  2. 另一种方法是通过初始化数组来使用指针,如下所示:

    array<vector<int> *, 3> a = {&v0, &v1, &v2};
    

答案 2 :(得分:0)

写一个tuple_assign函数:

template <class T>
using uncvref = std::remove_cv_t<std::remove_reference_t<T>>;

template <class T, class U, std::size_t...Is>
void tuple_assign_(T& to, U&& from, std::index_sequence<Is...>) {
    std::initializer_list<int>{
        (std::get<Is>(to) = std::get<Is>(std::forward<U>(from)), 0)...
    };
}

template <class T, class U,
    std::size_t TSize = std::tuple_size<uncvref<T>>::value,
    std::enable_if_t<TSize == std::tuple_size<uncvref<U>>::value, int*> = nullptr>
T& tuple_assign(T& to, U&& from) {
    tuple_assign_(to, std::forward<U>(from), std::make_index_sequence<TSize>{});
    return to;
}

并使用forward_as_tupleDEMO)包裹向量:

tuple_assign(a, std::forward_as_tuple(std::move(v0), std::move(v1), std::move(v2)));