c – 为什么不总是使用std :: forward?
发布时间:2020-12-16 03:44:44 所属栏目:百科 来源:网络整理
导读:std :: move和std :: forward之间的区别是众所周知的,我们使用后者保留转发对象的值类别,并使用前者转换为rvalue引用以启用移动语义. 在有效的现代C中,存在一种指导原则 use std::move on rvalue references, std::forward on universal references. 但在以
std :: move和std :: forward之间的区别是众所周知的,我们使用后者保留转发对象的值类别,并使用前者转换为rvalue引用以启用移动语义.
在有效的现代C中,存在一种指导原则
但在以下场景中(以及我们不想更改值类别的场景), template <class T> void f(vector<T>&& a) { some_func(std::move(a)); } 如果a不是转发引用而是简单的右值引用,那么执行以下操作是否完全相同? template <class T> void f(vector<T>&& a) { some_func(std::forward<decltype(a)>(a)); } 因为这可以很容易地封装在像这样的宏中, #define FWD(arg) std::forward<decltype(arg)>(arg) 如此总是使用这个宏定义不方便吗? void f(vector<T>&& a) { some_func(FWD(a)); } 写这两种方式不完全相同吗? 解决方法
呃.值得商榷.在您的特定示例中,它是等效的.但我不会养成习惯.一个原因是因为您希望在转发和移动之间进行语义区分.另一个原因是因为要拥有一致的API,除了FWD之外你还必须拥有MOV,这看起来很糟糕而且什么都不做.但更重要的是,您的代码可能会意外失败.
请考虑以下代码: #include <iostream> using namespace std; #define FWD(arg) std::forward<decltype(arg)>(arg) struct S { S() { cout << "S()n"; } S(const S&) { cout << "S(const S&)n"; } S(S&&) { cout << "S(S&&)n"; } }; void some_func(S) {} void f(S&& s) { some_func(FWD(s)); } int main() { f(S{}); } 打印出来
但是,如果我只是改变FWD线以获得另一对(看似可选的)括号,如下所示: void f(S&& s) { some_func(FWD((s))); } 现在我们得到了
这是因为现在我们在表达式上使用了decltype,它计算为左值引用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |