Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::move(*这)是一种好模式吗?_C++_C++11_This_Move Semantics_Lvalue - Fatal编程技术网

C++ std::move(*这)是一种好模式吗?

C++ std::move(*这)是一种好模式吗?,c++,c++11,this,move-semantics,lvalue,C++,C++11,This,Move Semantics,Lvalue,为了使带有C++11引用限定符的代码按预期工作,我必须引入一个听起来不正确的std::move(*this) #include<iostream> struct A{ void gun() const&{std::cout << "gun const&" << std::endl;} void gun() &&{std::cout << "gun&&&qu

为了使带有C++11引用限定符的代码按预期工作,我必须引入一个听起来不正确的
std::move(*this)

#include<iostream>
struct A{
    void gun() const&{std::cout << "gun const&" << std::endl;}
    void gun() &&{std::cout << "gun&&" << std::endl;}
    void fun() const&{gun();}
    void fun() &&{std::move(*this).gun();} // <-- is this correct? or is there a better option
};

int main(){
    A a; a.fun(); // prints gun const&
    A().fun(); // prints gun&&
}
但是同样,如果
gun
是(通用)接口的一部分,那么
std::move(*这个)
是必要的,但只有在那时。而且,即使
gun
不是接口的一部分,也不将函数
gun
拆分为两个不同名称的函数具有可读性优势,而且这样做的成本是,
std::move(*this)

编辑2:回想起来,这类似于C++98中相同函数的
const
和no-
const
重载的情况。在某些情况下,使用
const_cast
(cast的另一种形式)不重复代码并使两个函数具有相同的名称()是有意义的。
... 尽管在更复杂的情况下,使用辅助私有函数来委托接口函数的正确行为是有意义的。

是的,
*无论如何调用成员函数,此
始终是左值,因此如果希望编译器将其视为右值,您需要使用
std::move
或等效工具。考虑到这一类,它必须是:

struct A {
  void gun() &; // leaves object usable
  void gun() &&; // makes object unusable

  void fun() && {
    gun();
    gun();
  }
};
如果将
*此
设为右值,则表明
fun
gun
的第一次调用可能会导致对象无法使用。然后,第二次呼叫将失败,可能会严重失败。这不是应该暗中发生的事情


这也是为什么在
void f(T&&T)
中,
T
是左值的原因。在这方面,
*此
与任何参考函数参数没有区别。

是的,我理解。那么
std::move(*这个)
是使用调用链中所有
&&
函数的方法吗?(我澄清了上面的真实问题)@alfC是的,就像其他函数参数一样。调用者指定可以安全地从中移动对象,但被调用函数本身也需要这样做,因为编译器无法自动解决这个问题。(当然,由于
这个
是您自己的类类型,您也可以采用不同的方法:转发到可以对左值调用的私有破坏性成员函数。由于它是私有的,外部用户不能意外调用它。)我不理解另一种方法,使用私有破坏性(?)为了说明,示例中的第二个调用可能应该是
std::move(*this).gun()
@alfC任何
void gun()&&
可以做的事,
void gun()
可以做的事。因此,如果您想调用
void gun()&&
版本,您可以做的是实现
void gunRvalue()
,它是
私有的
,除非另有规定,否则通常不安全地调用左值。你可以从一个
public
函数调用它,比如:
void gun()&&{gunRvalue()}
,任何你想调用
void gun()&&&
版本的东西,都可以直接调用
gunRvalue()
。如果你不想使用
std::move
,那么
static\u cast(*this.gun()
?@yohjp,或者
std::forward(*this).gun()
,我建议创建一个名为
rvalue()
的成员函数,将
*this
作为rvalue返回。然后您可以调用
this->rvalue()->…
@Mehrdad,它是这样编写的函数吗
auto rvalue()->decltype(std::move(*this)){return std::move(*this);}
struct A {
  void gun() &; // leaves object usable
  void gun() &&; // makes object unusable

  void fun() && {
    gun();
    gun();
  }
};