С++ - создать новый конструктор для std::vector <double>?

Я написал собственный класс контейнера, который содержит экземпляр std::vector<double> - отлично работает. Для совместимости с другим API я хотел бы экспортировать содержимое контейнера в виде копии std::vector<double>. В настоящее время это работает:

MyContainer container;
....
std::vector<double> vc(container.begin(), container.end());

Но если возможно, хотелось бы написать:

MyContainer container;
....
std::vector<double> vc(container);

Могу ли я (легко) создать такой конструктор std::vector<double>?

Ответ 1

Вы можете создать явное преобразование в std::vector<double>:

explicit operator std::vector<double>() const {
    return std::vector<double>(begin(), end());
}

Затем std::vector<double> vc(container); вызовет конструктор перемещения std::vector<double>.

Обратите внимание, что конверсии, которые являются дорогостоящими с точки зрения вычислений, обычно не одобряются. Поэтому функция вектора factory может быть более разумным:

class MyContainer {
public:
    using value_type = double;
    // ...
};

template<typename Source>
auto to_vector(Source source) {
    return std::vector<typename Source::value_type>(source.begin(), source.end());
}

Затем вы должны написать:

MyContainer container;
// ...
auto vc = to_vector(container);

Это также более общее, поскольку оно работает со всем, что имеет совместимые члены value_type, begin и end.

Ответ 2

Могу ли я (легко) создать такой конструктор std::vector?

Нет, вы не можете, поскольку для этого потребуется изменить объявления класса std::vector.

Вы можете предоставить оператора трансляции для MyContainer до std::vector<double>, хотя.

Ответ 3

Вы не можете и не должны изменять API класса, который вы сами не пишете. Но я думаю, что в вашем случае оператор-транслятор будет делать все отлично. Например (это нужно -std=c++11):

#include <iostream>
#include <vector>

struct Foo
{
  operator std::vector<double> () const
  {
    return std::vector<double> { 1, 2, 3 };
  }
};

int main()
{
  Foo foo;
  std::vector<double> bar = foo; // Applies the cast operator defined in Foo
  std::cout << bar.size() << std::endl; // Prints "3"
  return 0;
}