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&.