c++ 20:如何发现模板参数是右值引用

siv3szwd  于 2023-03-14  发布在  其他
关注(0)|答案(2)|浏览(127)

我想给一个函数传递一个参数,做for,如果参数是rvalue,那么移动对象而不是复制,怎么做?

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;
}

UPD:auto tmp = std::forward<decltype(item)>(item)也将始终复制。

hgncfbus

hgncfbus1#

使用std::vector<std::string>&&呼叫时
那你就有

template<class T> void func(T&& v) // T = std::vector<std::string>

并且std::is_rvalue_reference_v<std::vector<std::string>>false
你需要std::is_rvalue_reference_v<T&&>
如果你用一些Obj&调用func,T将被推导为Obj&,并且T&&也将是(使用折叠规则)Obj&

sqyvllje

sqyvllje2#

不管v的真实的类型是什么,std::is_rvalue_reference_v<T>都会“提取”T,这就是为什么它总是false,总是没有&&.T,也就是说,不要做你正在做的事情,只要总是尝试std::move,如果它不可能移动,std::move将自动回退到副本。所以基本上您不必手动处理这种情况。

相关问题