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

时间:2017-01-11 20:31:26

标签: c++ arrays algorithm c++11 constexpr

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

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;
}

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

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;
}

使用g++ -std=c++14 main.cpp -o main进行编译时收到以下错误消息:

/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);

我根本不明白这个错误信息。 std::copy不是constexpr吗?如果不是,它应该是,对吗?如果std::copyconstexpr,我的代码是否有效?

2 个答案:

答案 0 :(得分:4)

你应该做一个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;
}

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

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

请注意,在C ++ 17之前,大多数std::array个访问者都不是constexpr

答案 1 :(得分:3)

constexpr暗示const

您的std::copy尝试修改const变量。

---编辑---

OP问

  

我正在实现一些使用大量预先计算的值的东西,这些值会回绕一次。如果不打印出值并将它们复制粘贴到我的代码中,我就无法做到这一点?

如下所示?

#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;
 }