I want to pass a parameter to a function, do for
, and if the argument is rvalue
, then move objects instead of copying. How to do that?
template<class T> void func(T&& v){
for (auto&& item : v) {
if constexpr (std::is_rvalue_reference_v<T>) { // ALWAYS FALSE
// move object
auto tmp = std::move(item);
}
else {
// copy object
auto tmp = item;
}
}
}
int main() {
std::vector<std::string> a {"11", "22"};
func(std::move(a));
std::cout << a[0].size(); // print 2 !! (must 0)
return 0;
}
>Solution :
when calling with std::vector<std::string>&&
then you have
template<class T> void func(T&& v) // T = std::vector<std::string>
and std::is_rvalue_reference_v<std::vector<std::string>>
is false
.
You need std::is_rvalue_reference_v<T&&>
.
If you call func with some Obj&
, T
would be deduced as Obj&
, and T&&
would also be (with collapsing rule) Obj&
.