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?

3
  • 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. Commented Dec 6, 2016 at 17:14
  • Are you planning to use C++17? en.cppreference.com/w/cpp/container/array/begin Commented Dec 6, 2016 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<int, 4> myarray2{a,b,c,d};. Commented Dec 6, 2016 at 17:44

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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());

3 Comments

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.
Can you give any concrete example.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.