当参数 class 没有移动构造函数时,IDE 推荐 'pass by value and use std move'

IDE recommends 'pass by value and use std move' when parameter class has no move constructor

struct Person
{
    int mId; 
    std::string mName; 

    Person(int id, std::string name) : mId(id), mName(std::move(name))
    {
    }
};

struct Node
{
    Person mData;  
    Node* mLeft;
    Node* mRight;

    Node(Person data) : mData(std::move(data)), mLeft(nullptr), mRight(nullptr)
    {}
};

在为我的 Person class 编写构造函数时,我最初将 'name' 参数定义为常量引用,但建议将其更改为 简单值并使用 std移动.

我理解这是因为右值字符串可用于初始化 'Person',在这种情况下,字符串将 移动 到变量 'name'而不是被复制。然后它将进一步 移动 到成员变量 'mName'- 通过 std::move。我也觉得这只适用于 std::string 因为它定义了一个移动构造函数。

不明白 的是为什么我被推荐在 'Node' class 构造函数中再次使用 std::move 因为我尚未为 Person 定义移动构造函数。此外,我注意到从 Person class 中删除字符串成员变量 mName 会停止此 IDE 推荐。

我猜这是因为Person的默认移动构造函数class。

(如果有帮助,我的IDE是VS2022,推荐来自扩展Resharper')

您的 Person class 遵循“rule-of-zero”,这意味着它没有声明任何 copy/move 操作或显式析构函数。

这通常是正确的做法,因为如果可能的话,编译器将隐式声明所有这些操作,并使用您通常期望从这些操作中获得的语​​义来定义它们。

在您的例子中,Person 的所有成员都可以是 move-constructed,因此 Person 的隐式移动构造函数将定义为 move-construct 成员 [=41] =].

这是在mData(std::move(data))中添加std::move时使用的。没有它 data 是一个左值,而不是 copy-constructs 每个成员将被使用的隐式复制构造函数。

Copy-constructing std::string 通常比 move-construct 成本更高,这可能是该工具警告这种情况的原因,但如果 std::string 不是'在那里。 Move-constructing和copy-constructing一个int成员是完全一样的操作。

如果您不想每次都检查 class 有哪些成员,您可以在这些情况下始终使用 std::move。例如,将 mId(id) 更改为 mId(std::move(id)) 是没有意义的,因为 id 是标量类型,但它也不会使任何事情变得更糟。