I have a function
class A { <has copy and move constructors > };
void f(A &&a) { ... }
I want to call the function f with a variable x
, but I want to run f
on a copy of x
, not x
itself. Why can't I do something like this?
f(copy(x));
But instead must do
f(A(x));
Is there anything similar to the copy
function I describe above?
Note: please don't tell me to add an overload f
that does the copying, I want something that doesn't require an overload and is explicit (i.e. copy
makes it clear to the reader that copying is done here)
What about this?
template <typename T>
T copy(T t) {return t;}
The copy is done when you pass t
by value and a following move take place.
http://coliru.stacked-crooked.com/a/cbc1a161f65a022b
If you can modify your function to:
void func(A) {}
then you can do
int main() {
A a;
func(a); //copies
func(std::move(a)); //moves
return 0;
}
Without any extra constructor call.
http://coliru.stacked-crooked.com/a/1bc80bcce64f242f
template<class T>
std::remove_cv_t<T> copy(T& t) {
return t;
}
template<class T>
void copy(T&&)=delete; // block rvalue copy
template<class T, size_t N>
void copy(T(&)[N]) = delete; // we can implement this if we want: see below
will copy any lvalue. On rvalues and non-copyable types (like arrays) it will fail to match or compile.
template<class T>
std::decay_t<T> copy_even_if_rvalue(T&& t) {
return std::forward<T>(t);
}
namespace details {
template<class T, size_t N, size_t...Is>
std::array<T, N> copy_even_if_rvalue(T(&arr)[N], std::index_sequence<Is...>)
{
return {{arr[Is]...}};
}
}
template<class T, size_t N>
std::array<T, N> copy_even_if_rvalue(T(&arr)[N]) {
return details::copy_even_if_rvalue(arr, std::make_index_sequence<N>{} );
}
template<class T, size_t N>
std::array<T, N> copy_even_if_rvalue(T(&&arr)[N]) {
return copy_even_if_rvalue(arr); // forward to lvalue version
}
will copy both rvalues and lvalues. Usually copy
is a smarter operation than copy_even_if_rvalue
in my opinion.
copy_even_if_rvalue
will convert raw C arrays into std::array
s, because that is about the only sensible way to copy them. An =delete
overload would be the other reasonable option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With