Reputation: 137890
C++11 introduces semantics to avoid unnecessarily copying objects, and std::move
to apply those semantics when otherwise a copy would occur. However, there are now also some cases where a copy is required, but not the default.
Consider this naive implementation of reverse
, for example. Because range-based for
uses perfect forwarding, modification to the container within the loop amounts to corruption.
auto out_iter = container.rbegin();
for ( auto value : container ) {
* out_iter ++ = value;
}
The goal is to fix this using
for ( auto value : copy( container ) ) {
It seems simple enough… accept any argument, get the underlying type and return a temporary copy.
Upvotes: 4
Views: 214
Reputation: 35459
The return type you're computing is better known as typename std::decay<T>::type
. Other than that, use std::forward
in the body to reap the full benefits of perfect forwarding:
template<typename T>
typename std::decay<T>::type
val(T&& t)
{ return std::forward<T>(t); }
Upvotes: 8