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

If the only way I can create myarray2 is to pass two std::array<int, 4>::iterator to the constructor, is it possible that I can make it with std::array, or do I have to use vector?

Rama
  • 3,222
  • 2
  • 11
  • 26
Esad
  • 107
  • 1
  • 8
  • 1
    A look at some basic reference material would reveal that the constructor is implicitly declared and must follow the rules of aggregate initialization. Since that does not include iterators, the answer is no. Do keep in mind that `std::array` represents a fixed/static array, like a traditional C-style array. – Cody Gray - on strike Dec 06 '16 at 17:14
  • Are you planning to use C++17? http://en.cppreference.com/w/cpp/container/array/begin – Rama Dec 06 '16 at 17:41
  • Since you know the size of the array, you can compute `*std::begin(myarray)`, `*std::next(std::begin(myarray))`, etc, and build myarray2 with the usual aggregate syntax `std::array myarray2{a,b,c,d};`. – Marc Glisse Dec 06 '16 at 17:44

2 Answers2

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

Where indexer is:

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

Which does the parameter pack expansion for us. Does no bounds checking. Not compiled, probably has tpyos.

C++14, I make no guarantees for MSVC to work.

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

Could be modified to work with non-random-access iterators I suspect.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
0

You can define your custom_array, which is inherited from standard 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; }
            }
        }
    };

Then you can declare your custom_array as you wish, example:

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());
  • The obviously disadvantage of doing this (inheritance) is that you lose the aggregate status of `std::array`, which is one of its primary advantages. [Aggregates cannot have base classes.](http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821) – Cody Gray - on strike Dec 07 '16 at 08:51
  • Can you give any concrete example. – Nhan Nguyen Tri Thanh Dec 07 '16 at 11:18
  • I don't know what you mean. A concrete example of an aggregate? `std::array` is an aggregate type. You lose that status when you inherit from it; your derived class `custom_array` is *not* an aggregate. For more on what aggregates are and how they're special, see [here](http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special). – Cody Gray - on strike Dec 07 '16 at 11:53