Слишком сложно. :) Просто соблюдайте правило, которому вы уже должны были следовать:
- Возьмите lhs
operator+
по значению
- реализовать
operator+
в единицах operator+=
на lhs
Это было уже верно в C ++ 03 из-за исключения копирования и RVO. Основное правило: если вы все равно делаете копию, сделайте это в параметрах.
Имея это в виду:
#include <iterator>
#include <utility>
class path
{
std::vector<std::string> path_;
public:
path& operator+=(path other)
{
auto op_begin = std::make_move_iterator(std::begin(other.path_));
auto op_end = std::make_move_iterator(std::end(other.path_));
path_.reserve(path_.size() + other.path_.size());
path_.insert(std::end(path_), op_begin, op_end);
return *this;
}
};
path operator+(path lhs, path rhs)
{
return std::move(lhs += std::move(rhs));
}
Это должна быть самая оптимальная форма. Обратите внимание, что я также изменил ваш operator+=
, чтобы фактически добавить путь, а не готовый (я надеюсь, это то, что вы имели в виду. Если нет, смело меняйте его на std::begin(path_)
снова).
Я также сделал rhs из значений operator+
и operator+=
, а затем просто переместил их. std::make_move_iterator
также хорошая утилита. Как следует из названия, вместо копирования он перемещает наведенные элементы. Это действительно должно быть так быстро, как это будет.
Другая версия может заключаться в использовании версии итератора std::move
в operator+=
:
path& operator+=(path other)
{
path_.reserve(path_.size() + other.path_.size());
std::move(other.begin(), other.end(), std::back_inserter(path_));
return *this;
}