2016-12-06 31 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的唯一途徑是通過兩項std::array<int, 4>::iterator的構造,是有可能,我可以std::array做呢,還是我必須使用vector使用begin()和end()可以創建std :: array嗎?

+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))'等,並用通常的聚合語法'std :: array myarray2 {a,b,c,d};構建myarray2。 –

回答

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

其中indexer是:

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

它執行參數包擴展我們。沒有邊界檢查。沒有編譯,可能有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

這樣做(繼承)的明顯缺點是你失去了'std :: array'的集合狀態,這是它的主要優點之一。 [Aggregates can not have base classes。](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-特別)。 –

相關問題