user5545734
user5545734

Reputation:

Copy conversion to standard containers in C++

This question is a continuation of How to convert an array into a vector in C++?, where I was suggested to use very tricky technique with a few sizeof() manipulations.

Actually I expected to find some function in standard library to convert an array into any container. I tried to write one by myself and it does not look very hard:

#include <list>
#include <vector>

// from C-array to std-container
template<typename T, int N>
auto make_copy(auto (&from)[N]) 
    { return T{ std::begin(from), std::end(from) }; }

// from std::container to another std::container
template<typename T>
auto make_copy(const auto &from) 
    { return T{ std::begin(from), std::end(from) }; }

int main()
{
    int myArray[2] = { 1, 2 };
    auto myVector = make_copy<std::vector<int>>( myArray );
    auto myList = make_copy<std::list<int>>( myVector );
    return myList.size();
}

https://gcc.godbolt.org/z/fv4ddadax

Is there anything similar to make_copy in the standard C++ library or in boost?

Upvotes: 1

Views: 153

Answers (2)

eerorika
eerorika

Reputation: 238341

where I was suggested to use very tricky technique with a few sizeof() manipulations.

sizeof is entirely unnecessary for arrays. If you need the size in number of elements, you can use std::size. But in this case, I would recommend what you used in your example: (technically, myArray works just as well as std::begin(myArray), but latter is nice for consistency):

std::vector myVector(std::begin(myArray), std::end(myArray));

Is there anything similar to make_copy in the standard C++ library

No.

For your suggestion, you don't need the array overload because the more general one works equally well. You could improve it a bit by using std::ranges::begin and end to support ranges that don't work with std::begin and end.

or in boost?

Yes:

auto myVector = boost::copy_range<std::vector<int>>(myArray);

Upvotes: 2

康桓瑋
康桓瑋

Reputation: 42766

You can use range-v3's ranges::to:

#include <range/v3/range/conversion.hpp>
#include <list>

int main() {
  int myArray[2] = {1, 2};
  auto myVector = ranges::to<std::vector>(myArray);
  auto myList = ranges::to<std::list>(myVector);
  return myList.size();
}

Demo.

Upvotes: 3

Related Questions