С++ 11 передать вектор в конструктор
Я весь день читаю об эффективном способе передачи аргументов, и я в замешательстве. Я хочу передать такой вектор:
Foo f({1,2,3});
Мне просто нужно инициализировать переменную _member с переданным вектором. Теперь вопрос в том, как должен выглядеть мой конструктор:
// pass by value
Foo (vector<int> vec) : _member{vec} {}
// const reference
Foo (const vector<int>& vec) : _member{vec} {}
// rvalue reference
Foo (vector<int>&& vec) : _member{std::move(vec)} {}
Ответы
Ответ 1
Самый простой подход - взять вектор по значению и переместить его:
Foo (vector<int> vec) : _member{std::move(vec)} {}
По сравнению с парой перегрузок const vector<int>&
/vector<int>&&
вы платите за один дополнительный ход (что очень дешево для векторов), но не нужно писать два конструктора (которые могут быстро взорваться, если вы имеют более одного параметра).
Ответ 2
В настоящее время во многих кругах проходит по модам. Я думаю, что это хороший выбор для конструкторов по разным причинам, поэтому я согласен с T.C. ответ. Однако, более широкий вопрос о наилучшем способе передачи аргументов (к неконструкторским функциям), я редко рекомендую передавать по значению. Я действительно очень рекомендую слушать эту часть беседы с Herb Sutter по теме: https://youtu.be/xnqTKD8uD64?t=51m34s.
Подводя итог, за пределами конструкторов: pass by value дает худшие гарантии производительности по сравнению с простым проходом by const-ref, он дает худшую производительность, чем перегрузки const-ref/rvalue-ref во всех случаях, это делает его сложнее для предоставления исключений, он разрезает полиморфные типы, он не может использоваться, когда копирование является условным.
В большинстве ситуаций вы либо не заботитесь о производительности по причине, либо заботитесь о многом. В первом случае использование const-ref проще и проще. Во втором случае пропуск по значению недостаточно хорош. Опять же, имейте в виду, что конструкторы различны по нескольким причинам (они перемещают конструкцию, а не переносят назначение, они принимают много аргументов, которые сильно влияют на количество перегрузок, которые вам нужны).
К сожалению, такого простого ответа на этот вопрос нет. В конечном счете оба подхода достаточно хороши, но я думаю, что для освоения С++ вы хотите знать плюсы и минусы обоих.
Ответ 3
В этом конкретном случае вы передаете rvalue
, поэтому третий вариант является лучшим.