考虑以下:
struct X
{
Y y_;
X(const Y & y) :y_(y) {}
X(Y && y) :y_(std::move(y)) {}
};
为了充分利用移动语义,是否有必要定义像第二个这样的构造函数?还是会在适当的情况下自动处理?
考虑以下:
struct X
{
Y y_;
X(const Y & y) :y_(y) {}
X(Y && y) :y_(std::move(y)) {}
};
为了充分利用移动语义,是否有必要定义像第二个这样的构造函数?还是会在适当的情况下自动处理?
是的,但是没有。你的代码应该是这样的:
struct X
{
Y y_;
X(Y y) : // either copy, move, or elide a Y
y_(std::move(y)) // and move it to the member
{}
};
如果您曾经在设计中说“我需要我自己的数据副本”*,那么您应该按值获取参数并将其移动到需要的位置。决定如何构造该值不是您的工作,这取决于该值的可用构造函数,所以让它做出选择,无论它是什么,并使用最终结果。
*当然,这也适用于函数,例如:
void add_to_map(std::string x, int y) // either copy, move or elide a std::string
{
// and move it to where it needs to be
someMap.insert(std::make_pair(std::move(x), y));
}
请注意,这在某种程度上也适用于 C++03,如果一个类型是默认可构造和可交换的(无论如何都是移动的):
// C++03
struct X
{
std::string y_;
X(std::string y) // either copy or elide a std::string
{
swap(y_, y); // and "move" it to the member
}
};
尽管这似乎没有被广泛采用。
是的,这是必要的。const ref 只能是副本,不能是移动。