2017-01-11 5 views
0

次のコードでは、長さ6の配列を作成し、最初の3つの要素に1、2、3で初期化します。次に、最初の3つの要素を最後の3つの要素にコピーします。次に、すべての要素を順番に印刷します。std :: copyを使って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); 

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

それは正常に動作しますが、私は、配列constexprを作るしようとすると、それは、もはやコンパイルしません:

g++ -std=c++14 main.cpp -o mainしてコンパイル
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; 
} 

私は、次のエラーメッセージが出ます:

/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::copyconstexprではありませんか?そうでなければ、それは正しいはずですか? std::copyconstexprの場合、私のコードは機能しますか?

+2

配列がconstの場合は変更できません。 –

+0

私は新しいC++機能について多くの経験はありませんが、あとで変更したい場合は配列constexprを宣言するのは意味がありません。どちらの配列も一定であるかどうか。 – Phil1970

+0

@lateeveloperどのように私は 'const'ではないコンパイル時にものを作る? –

答えて

3

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

しかし、あなたはそれが標準ライブラリでconstexprとしてマークされていないので、copyの独自のバージョンを作成する必要があります。

コンパイル時配列の値を変更することは意味をなさないが、実行時に変数の型を変更するようにコンパイラに依頼するのと同じことだ。コンパイラは実行時にも存在しません。しかし、constexpr関数はコンパイラによって実行されるので、値を変更するよう依頼するのはまだ理にかなっています。これが上のコードが理にかなっている理由です。

std::arrayアクセサのほとんどは、C++ 17までconstexprではありません。

+0

['std :: array :: begin()'](http://en.cppreference.com/w/cpp/container/array/begin)にも注意してください。 )、 '' std :: array :: end() '](http://en.cppreference.com/w/cpp/container/array/end)であり、他のアクセサはすべて' constexpr'だけです。 17。 –

+0

@yurikilochek確かに、私はそれを答えに加えます。 –

+0

ありがとうございます。私は本当にあなたの2番目の文に感謝します。私は 'constexpr'のconstanceについて混乱しました。コンパイル時に評価されるようにするには、何かが 'const'でなければならないということは、私にとってはまだ意味がありません。実行時に変更される巨大な配列を事前計算する必要がある場合はどうなりますか? –

3

constexprconstを意味する。

std::copyconst変数を変更しようとしました。

--- EDIT ---

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

どうしたらいいですか?私は実行時に 'const'という配列を気にしませんが、コンパイル時にプログラムで編集できるようにしたいと思います。 –

+0

constにしないでください。変更したいのであれば、なぜそれをconstにしますか? –

+0

@WillyGoat - 'const'(' constexpr')変数は初期化のみできます。初期化ですべての値を挿入する必要があります。コンパイル時に何かしたいのであれば、 'constexpr'かtemplapeの引数でなければなりません。 – max66

関連する問題