gpt4 book ai didi

c++ - std::move(*this) 是一个好的模式吗?

转载 作者:IT老高 更新时间:2023-10-28 12:43:49 26 4
gpt4 key购买 nike

为了使这个带有 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&&
}

这听起来有些不对劲。 std::move 有必要吗?这是推荐的用途吗? 目前,如果我不使用它,我在这两种情况下都会得到 gun const&,这不是预期的结果。

(似乎 *this 始终是隐式和左值引用,这是有道理的,但这是使用 move 的唯一方法)

使用 clang 3.4gcc 4.8.3 测试。


编辑:这是我从@hvd 的回答中了解到的:

  1. std::move(*this) 在语法和概念上都是正确的

  2. 但是,如果 gun 不是所需接口(interface)的一部分,则没有理由重载它的 lv-ref 和 rv-ref 版本。两个不同名字的函数可以做同样的工作。毕竟 ref-qualifiers 在接口(interface)级别很重要,这通常只是公共(public)部分。

struct A{
private:
void gun() const{std::cout << "gun const&" << std::endl;}
void gun_rv(){std::cout << "gun called from fun&&" << std::endl;}
public:
void fun() const&{gun();}
void fun() &&{gun_rv();} // no need for `std::move(*this)`.
};

但同样,如果 gun 是(通用)接口(interface)的一部分,那么 std::move(*this) 是必要的,但仅此而已。而且,即使 gun 不是接口(interface)的一部分,在不将函数 gun 拆分为两个不同命名的函数方面也有可读性优势,这样做的代价是,嗯.. ., std::move(*this).

EDIT 2:回想起来,这类似于 C++98 的 const 和无 const 重载相同函数的情况.在某些情况,使用 const_cast(另一种形式的强制转换)来不重复代码并让两个函数具有相同的名称(https://stackoverflow.com/a/124209/225186)是有意义的。...虽然在更复杂的情况下,使用辅助私有(private)函数来委托(delegate)接口(interface)函数的正确行为是有意义的。

最佳答案

是的,*this 始终是左值,无论成员函数如何调用,所以如果想让编译器将其视为右值,则需要使用 std: :move 或等效的。考虑到这个类,它必须是:

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

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

使 *this 成为右值意味着 fungun 的第一次调用可能会使对象无法使用。然后第二次调用将失败,可能很糟糕。这不应该隐含地发生。

这也是为什么在 void f(T&& t) 中,t 是一个左值的原因。在这方面,*this 与任何引用函数参数没有什么不同。

关于c++ - std::move(*this) 是一个好的模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25334698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com