How do you copy a constexpr array to another constexpr array with std::copy?

狂风中的少年 提交于 2019-12-11 04:13:07

问题


In the following code, I create an array of length 6 and initialize it with 1, 2 and 3 in the first 3 elements. Then I copy the first 3 elements to the last 3 elements. Then I print all the elements in order.

std::array<int, 6> bar = {1, 2, 3};

int main(){
    // Copy the first 3 elements to the last 3 elements
    std::copy(bar.begin(), bar.end() - 3, bar.end() - 3);

    // Print all the elements of bar
    for(auto& i: bar) std::cout << i << std::endl;
}

It works fine, but when I try to make the array constexpr it no-longer compiles:

constexpr std::array<int, 6> bar = {1, 2, 3};

int main(){
    // Copy the first 3 elements to the last 3 elements
    std::copy(bar.begin(), bar.end() - 3, bar.end() - 3); // Won't compile!

    // Print all the elements of bar
    for(auto& i: bar) std::cout << i << std::endl;
}

Compiling with g++ -std=c++14 main.cpp -o main I get the following error message:

/usr/include/c++/5/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = const int*]’:
/usr/include/c++/5/bits/stl_algobase.h:438:45:   required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = const int*]’
/usr/include/c++/5/bits/stl_algobase.h:471:8:   required from ‘_OI std::copy(_II, _II, _OI) [with _II = const int*; _OI = const int*]’
main.cpp:115:53:   required from here
/usr/include/c++/5/bits/stl_algobase.h:402:44: error: no matching function for call to ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const int*&, const int*&, const int*&)’
                        _Category>::__copy_m(__first, __last, __result);
                                            ^
/usr/include/c++/5/bits/stl_algobase.h:373:9: note: candidate: template<class _Tp> static _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = false]
         __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
         ^
/usr/include/c++/5/bits/stl_algobase.h:373:9: note:   template argument deduction/substitution failed:
/usr/include/c++/5/bits/stl_algobase.h:402:44: note:   deduced conflicting types for parameter ‘_Tp’ (‘int’ and ‘const int’)
                        _Category>::__copy_m(__first, __last, __result);

I don't understand this error message at all. Is std::copy not constexpr? If it isn't, it should be, right? Does my code would work if std::copy was constexpr?


回答1:


You should make a constexpr function. constexpr imply const, but not inside the scope of a constexpr function.

constexpr auto get_bar() {
    std::array<int, 6> bar = {1, 2, 3, 0, 0, 0};

    copy(bar.begin(), bar.end() - 3, bar.end() - 3);

    return bar;
}

However, you will need to write your own version of copy because it's not marked as constexpr in the standard library.

Changing the value of a compile time array does not make sense, it's the same thing as asking the compiler to change the type of a variable at runtime. The compiler don't even exist during runtime. However, a constexpr function is executed by the compiler, so it's still make sense to ask it to mutate values. This is why the code above make sense.

Note that most of std::array accessors are not constexpr until C++17.




回答2:


constexpr imply const.

Your std::copy try to modify a const variable.

--- EDIT ---

The OP ask

I'm implementing something that uses a very large array of precomputed values which wrap around once. I can't do this without printing out values and copy-pasting them into my code?

What about something as follows?

#include <array>
#include <iostream>

template <int ... I>
struct foo
 { std::array<int, 2U*sizeof...(I)> bar { { I..., I... } }; };

int main()
 {
   foo<2, 3, 5, 7, 11, 13> v;

   for ( auto const & i : v.bar )
      std::cout << i << ", ";

   // the for print 2, 3, 5, 7, 11, 13, 2, 3, 5, 7, 11, 13,

   std::cout << std::endl;
 }


来源:https://stackoverflow.com/questions/41600157/how-do-you-copy-a-constexpr-array-to-another-constexpr-array-with-stdcopy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!