2016-12-06 120 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-特别)。 –

相关问题