1

If I have a std::vector-wrapper, do I forward it to my underlying vector as:

void vector_wrapper::emplace_back(value_type&& val) { 
  wrapped_vector_.emplace_back(std::move(val)); 
}

or

void vector_wrapper::emplace_back(value_type&& val) {
  wrapped_vector_.emplace_back(val); 
}

?

Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90
  • 4
    A named rvalue reference is an lvalue, so use `std::move`. – Xeo Jun 19 '13 at 09:30
  • 2
    [This](http://stackoverflow.com/questions/14351669/rvalue-reference-why-arent-rvalues-implicitly-moved) question could be helpful. Also I suggest change your `emplace_back` to accept variable number of arguments(like in the `vector`), since element may be constructed with more than one argument. – awesoon Jun 19 '13 at 09:30
  • 1
    Xeo: Could you make an answer of that so I can mark it? – Viktor Sehr Jun 19 '13 at 13:03

1 Answers1

3

If value_type is a deduced template parameter, use std::forward<value_type>(val) (from the <utility> header); this is part of the perfect forwarding recipe. If not, and value_type is a specific type (including a non-deduced template parameter), use std::move(val) (also from <utility>). If you take soon's advice and make emplace_back() take a variable number of arguments, that will (most likely) mean using a variadic template and perfect forwarding, which means forward<T> would be the appropriate construct.

Examples:

Perfect forwarding:

template<typename... P>
void vector_wrapper::emplace_back( P &&...p ) {
    wrapped_vector_.emplace_back( std::forward<P>(p)... );
}

Specific or non-deduced type for value_type:

void vector_wrapper::emplace_back( value_type &&val ) {
    wrapped_vector_.emplace_back( std::move(val) );
}
    // Note: emplace_back() idiomatically uses perfect forwarding,
    // so the first example would typically be more appropriate.
    // This second form is more applicable to push_back()

(Technically, you can use std::forward<>() for both cases, since it is equivalent to std::move() for non-lvalue-reference types, and is therefore a fancier way of writing std::move(). But it is more concise to say std::move() when the type-introspection of forward<> isn't needed, and more significantly, it better communicates the intent of the code.)

Adam H. Peterson
  • 4,511
  • 20
  • 28