2016-12-04 9 views
4

は私がstd::tie経由std::arrayを展開しようとした:のstd ::を開梱配列

#include <tuple> 
#include <array> 

int main() { 
    std::array<int, 3> arr = {1, 2, 3}; 
    int a, b, c; 
    std::tie(a, b, c) = arr; 
    return 0; 
} 

これは打ち鳴らすに動作しますが、G ++ 5.4でコンパイルに失敗:no match for ‘operator=’。コンパイルオプションは-std=c++11です。

  1. gangではなくg ++で動作するのはなぜですか?
  2. std::arrayは、タプルを解凍するとどうやって移植可能ですか?

ありがとうございました!

+0

おそらく、 'libC++'実装によって何か追加されましたか? – Arunmu

+0

[Visual Studio 2015でコンパイルされません](http://rextester.com/BXYD49474) – PaulMcKenzie

+1

これは3.2以降のclangのバージョンではコンパイルされません。 [リンクをクリックするとコマンドラインオプションが失われてしまうので、 '-std = C++ 11'を追加してください) – PaulMcKenzie

答えて

1

私は、配列をタプルに変換する専用の関数を作成します。次のようにC++ 14のコードでは、なります:その後、

template <class T, std::size_t N, std::size_t... Is> 
auto unpack_impl(std::array<T, N> &arr, index_sequence<Is...>) -> decltype(std::make_tuple(arr[Is]...)) { 
    return std::make_tuple(arr[Is]...); 
} 

template <class T, std::size_t N> 
auto unpack(std::array<T, N> &arr) -> decltype(unpack_impl(arr, make_index_sequence<N>{})) { 
    return unpack_impl(arr, make_index_sequence<N>{}); 
} 

など、それを使用します。C++ 11では

std::array<int, 3> arr = {{1, 2, 3}}; 
int a, b, c; 
std::tie(a, b, c) = unpack(arr); 

を、それはの出ないよう、あなたがinteger_sequenceを実装するが必要があるだろうし標準のボックス...

Here完全なC++ 11ソリューションを見つけることができます。

編集:

配列を使用すると、不要なコピーを避けたいと思うかもしれないいくつかのより複雑なオブジェクトが含まれている場合。

template <class T, std::size_t N, std::size_t... Is> 
auto unpack_impl(std::array<T, N> &arr, index_sequence<Is...>) -> decltype(std::tie(arr[Is]...)) { 
    return std::tie(arr[Is]...); 
} 

EDIT2:

This one VSにもコンパイルconst性は、あなたは可能性がアップし、簡単なタイの配列要素はあなたを気にしない場合、代わりにmake_tupleのあなたがまたはconstの参照のタプルを使用することを行うために、

関連する問題