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++ вы хотите знать плюсы и минусы обоих.