当参数 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
是标量类型,但它也不会使任何事情变得更糟。
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
是标量类型,但它也不会使任何事情变得更糟。