左值引用限定函数可以直接在右值引用限定函数中使用吗?
Can a lvalue-ref-qualified function be used directly in a rvalue-ref-qualified function?
我一直在编写以下代码来支持对右值的函数调用,而无需在 return 值上显式 std::move
。
struct X {
X& do_something() & {
// some code
return *this;
}
X&& do_something() && {
// some code
return std::move(*this);
}};
但这导致不得不重复函数内的代码。最好,我会做类似
的事情
struct X {
X& do_something() & {
// some code
return *this;
}
X&& do_something() && {
return std::move(do_something());
}};
这是一个有效的转换吗?为什么或为什么不?
此外,我不禁觉得在 w.r.t ref-qualifiers 方面存在一些知识差距。是否有通用的方法(或一组规则)来确定这样的代码是否有效?
Is this a valid transformation?
是的。在成员函数中 *this
总是一个左值。即使该函数是右值引用限定的。与
相同
void foo(bar& b) { /* do things */ }
void foo(bar&& b) {
// b is an lvalue inside the function
foo(b); // calls the first overload
}
因此您可以使用左值引用限定函数来共享实现。
并且在结果上使用std::move
也没有问题。第一个重载只能 return 一个左值引用,因为据它所知,它是在一个左值上调用的。同时,第二个重载有一些额外的信息,它知道它最初是在右值上调用的。因此,它会根据附加信息进行额外的转换。
std::move
只是将左值转换为右值的命名转换。它的目的是向指定的对象发出信号,就好像它即将过期一样。由于您是在您知道这是真的上下文中执行此转换(该成员最初是在绑定到右值引用的对象上调用的),所以它应该不会造成问题。
我一直在编写以下代码来支持对右值的函数调用,而无需在 return 值上显式 std::move
。
struct X {
X& do_something() & {
// some code
return *this;
}
X&& do_something() && {
// some code
return std::move(*this);
}};
但这导致不得不重复函数内的代码。最好,我会做类似
的事情struct X {
X& do_something() & {
// some code
return *this;
}
X&& do_something() && {
return std::move(do_something());
}};
这是一个有效的转换吗?为什么或为什么不?
此外,我不禁觉得在 w.r.t ref-qualifiers 方面存在一些知识差距。是否有通用的方法(或一组规则)来确定这样的代码是否有效?
Is this a valid transformation?
是的。在成员函数中 *this
总是一个左值。即使该函数是右值引用限定的。与
void foo(bar& b) { /* do things */ }
void foo(bar&& b) {
// b is an lvalue inside the function
foo(b); // calls the first overload
}
因此您可以使用左值引用限定函数来共享实现。
并且在结果上使用std::move
也没有问题。第一个重载只能 return 一个左值引用,因为据它所知,它是在一个左值上调用的。同时,第二个重载有一些额外的信息,它知道它最初是在右值上调用的。因此,它会根据附加信息进行额外的转换。
std::move
只是将左值转换为右值的命名转换。它的目的是向指定的对象发出信号,就好像它即将过期一样。由于您是在您知道这是真的上下文中执行此转换(该成员最初是在绑定到右值引用的对象上调用的),所以它应该不会造成问题。