c++ 20: how to find that the template argument is a rvalue reference

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

Leave a Reply