如何使用 std::copy 将 constexpr 数组复制到另一个 constexpr 数组?

Wil*_*oat 2 c++ arrays algorithm constexpr c++11

在下面的代码中,我创建了一个长度为 6 的数组,并在前 3 个元素中使用 1、2 和 3 对其进行初始化。然后我将前 3 个元素复制到后 3 个元素。然后我按顺序打印所有元素。

\n\n
std::array<int, 6> bar = {1, 2, 3};\n\nint main(){\n    // Copy the first 3 elements to the last 3 elements\n    std::copy(bar.begin(), bar.end() - 3, bar.end() - 3);\n\n    // Print all the elements of bar\n    for(auto& i: bar) std::cout << i << std::endl;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它工作正常,但是当我尝试创建数组时,constexpr它不再编译:

\n\n
constexpr std::array<int, 6> bar = {1, 2, 3};\n\nint main(){\n    // Copy the first 3 elements to the last 3 elements\n    std::copy(bar.begin(), bar.end() - 3, bar.end() - 3); // Won't compile!\n\n    // Print all the elements of bar\n    for(auto& i: bar) std::cout << i << std::endl;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译g++ -std=c++14 main.cpp -o main我收到以下错误消息:

\n\n
/usr/include/c++/5/bits/stl_algobase.h: In instantiation of \xe2\x80\x98_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = const int*]\xe2\x80\x99:\n/usr/include/c++/5/bits/stl_algobase.h:438:45:   required from \xe2\x80\x98_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = const int*]\xe2\x80\x99\n/usr/include/c++/5/bits/stl_algobase.h:471:8:   required from \xe2\x80\x98_OI std::copy(_II, _II, _OI) [with _II = const int*; _OI = const int*]\xe2\x80\x99\nmain.cpp:115:53:   required from here\n/usr/include/c++/5/bits/stl_algobase.h:402:44: error: no matching function for call to \xe2\x80\x98std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const int*&, const int*&, const int*&)\xe2\x80\x99\n                        _Category>::__copy_m(__first, __last, __result);\n                                            ^\n/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]\n         __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)\n         ^\n/usr/include/c++/5/bits/stl_algobase.h:373:9: note:   template argument deduction/substitution failed:\n/usr/include/c++/5/bits/stl_algobase.h:402:44: note:   deduced conflicting types for parameter \xe2\x80\x98_Tp\xe2\x80\x99 (\xe2\x80\x98int\xe2\x80\x99 and \xe2\x80\x98const int\xe2\x80\x99)\n                        _Category>::__copy_m(__first, __last, __result);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我根本不明白这个错误消息。不是?std::copyconstexpr如果不是,那也应该是吧?std::copy如果是的话我的代码还能工作吗constexpr

\n

Gui*_*cot 5

您应该创建一个 constexpr 函数。constexpr暗示 const,但不在函数范围内constexpr

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;
}
Run Code Online (Sandbox Code Playgroud)

但是,您需要编写自己的版本,copy因为它没有constexpr在标准库中标记为。

更改编译时数组的值没有意义,这与要求编译器在运行时更改变量的类型是一样的。编译器在运行时甚至不存在。然而,constexpr 函数是由编译器执行的,因此要求它改变值仍然是有意义的。这就是上面的代码有意义的原因。

请注意,大多数std::array访问器直到constexprC++17 才出现。