C++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)} {}

3 ответов


самый простой подход-взять вектор по значению, и двигать его:

Foo (vector<int> vec) : _member{std::move(vec)} {}

по сравнению с парой const vector<int>&/vector<int>&& перегрузки, вы платите до одного дополнительного хода (что очень дешево для векторов), но не должны писать два конструктора (которые могут взорваться довольно быстро, если у вас есть более одного параметра).


Pass by value является модным в настоящее время во многих кругах. Я думаю, что это хороший выбор для конструкторов по разным причинам, поэтому я согласен с ответом T. C. Однако, более широкий вопрос о наилучшем способе передачи аргументов (к функциям, не являющимся конструкторами), я редко рекомендую передавать по значению. Я очень, очень настоятельно рекомендую послушать эту часть разговора Херба Саттера на эту тему:https://youtu.be/xnqTKD8uD64?t=51m34s.

подводя итог, за пределами конструкторы: pass by value дает худшие гарантии производительности в худшем случае по сравнению с простым pass by const-ref, он дает худшую производительность, чем перегрузки const-ref/rvalue-ref во всех случаях, это затрудняет предоставление гарантий исключения, он срезает полиморфные типы, его нельзя использовать при условном копировании.

в большинстве ситуаций, вы либо не заботитесь о производительности в пределах разумного, или вы заботитесь много. В первом случае использование const-ref проще и проще. Во втором кейс, пропуск по стоимости недостаточно хорош. Опять же, имейте в виду, что конструкторы отличаются по нескольким причинам (они перемещают построение вещей вместо назначения перемещения, они принимают много аргументов, которые сильно влияют на количество необходимых перегрузок).

к сожалению, на этот вопрос нет такого простого ответа. В конечном счете оба подхода достаточно хорошо, но я думаю, чтобы освоить c++ вы хотите знать плюсы и минусы обоих.


в этом конкретном случае вы передаете rvalue таким образом, третий выбор является лучшим.