2016-12-06 1 views
2
std::array<int, 4> myarray = {1, 2, 3, 4}; 
std::array<int, 4> myarray2(std::begin(myarray),std::end(myarray)); //It throws error 

私はmyarray2を作成することができる唯一の方法は、コンストラクタに2 std::array<int, 4>::iteratorを通過させることであるならば、それは私がstd::arrayでそれを作ることができ、または私はvectorを使わなければいけないことがありますか?私たちのために、パラメータパックの拡張を行いbegin()とend()を使ってstd :: arrayを作成することはできますか?

template<class=void,std::size_t...Is> 
auto indexer(std::index_sequence<Is...>){ 
    return [](auto&&f)->decltype(auto){ 
    return decltype(f)(f)(std::integral_constant<std::size_t,Is>{}...); 
    }; 
} 
template<std::size_t N> 
auto indexer(){ 
    return indexer(std::make_index_sequence<N>{}); 
} 

indexerがある

+1

いくつかの基本的な参考資料を見ては、コンストラクタが暗黙的に宣言されていることを明らかにすると集計の初期化の規則に従わなければなりません。それにはイテレータは含まれていないので、答えはノーです。 'std :: array'は、従来のCスタイルの配列のような固定/静的配列を表していることに注意してください。 –

+0

C++ 17を使用する予定ですか? http://en.cppreference.com/w/cpp/container/array/begin – Rama

+0

配列のサイズを知っているので、あなたは '* std :: begin(myarray)'、 '* std :: next std :: begin(myarray)) 'などのようにして、myarray2を通常の集約構文' std :: array myarray2 {a、b、c、d}; 'でビルドします。 –

答えて

1
template<class T, std::size_t N, class It> 
std::array<T,N> array_from_iterator(It it){ 
    return indexer<N>()(
    [it](auto...Is)->std::array<T,N> 
    { 
     return { (*(it+Is))... }; 
    } 
); 
} 

。境界チェックはしません。コンパイルされていない、おそらくtpyosがあります。

C++ 14、私はMSVCが動作することを保証しません。

std::array<int, 4> myarray2 = array_from_iterator<int,4>(std::begin(myarray)); 

私が疑うことのない非ランダムアクセスイテレータで動作するように変更することができます。

0

custom_arrayは、標準のstd :: arrayから継承されています。あなたが望むよう

template<typename _T, size_t _size> 
    class custom_array : public std::array<_T, _size> { 
    public: 
     custom_array(std::array<_T, _size> arr, 
        size_t start, 
        size_t end) { 

      size_t itr = 0; 

      while (itr < this->size() && 
        start < arr.size() && 
        start <= end) { 
       this->_Elems[itr++] = arr[start++]; 
      } 
     } 

     custom_array(std::array<_T, _size>::iterator start, 
        std::array<_T, _size>::iterator end) { 
      size_t itr = 0; 
      while (itr < this->size()) { 
       this->_Elems[itr++] = *start; 
       start++; 
       if (start == end) { break; } 
      } 
     } 
    }; 

その後は、例をごcustom_arrayを宣言することができます。

std::array<int, 4> arr = { 1, 2, 3, 4 }; 
custom_array<int, 4> arr_1(a, 0, 4); 
custom_array<int, 4> arr_2(a.begin(), a.end()); 
+0

この(継承)を行うことの明らかな欠点は、主な利点の1つである 'std :: array'の集約ステータスを失うことです。 [集計は基本クラスを持つことができません。](http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821) –

+0

具体的な例を挙げてください。 –

+0

あなたは何を意味するのか分かりません。集合体の具体例? 'std :: array'は集約型です。あなたはそれを継承するときにその状態を失います。派生クラス 'custom_array'は集約ではありません。集約が何で、どのように特殊であるかについては、[ここ](http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-特別)。 –

関連する問題