如何同时使用变量和移动变量?
How to use variable and move variable at the same time?
假设我们有以下代码:
struct some_class : parent
{
some_class(::other_class oth) :
parent(some_function(oth.some_property), std::move(oth))
{}
};
当然,构造会导致未定义的行为(在我的例子中是崩溃),因为 c++ 没有指定执行顺序。但是,我怎样才能在移动之前取回 属性 呢?我无法更改 parent.
创建一个辅助函数来构造可以添加排序的父级:
parent make_parent(::other_class &&oth) {
auto sf = some_function(oth.some_property);
return parent(sf, std::move(oth));
}
some_class(::other_class oth) :
parent(make_parent(std::move(oth))
{}
正如您所注意到的,问题是由于未指定的执行顺序造成的。
您可以通过使 parent
通过右值引用而不是左值获取对象来摆脱未定义的行为。这样它就获得了对现有对象的引用,并且该对象在内存中的数据实际上不会被移动。即:
struct parent {
parent (int thing, SomeProperty && some_property) { /* Do stuff. */ }
};
在这种情况下,std::move
何时在 oth
上执行并不重要。它的数据实际上不会被移动到另一个对象中,因为 parent
需要一个右值引用。因此,即使首先调用 std::move
,您的 some_function
(我假设它通过 const 左值引用获取 oth
)也将有一个合适的对象可以使用。
这里的主要缺点是父级现在总是需要右值。所以你不能在不移动它的情况下将对象传递给它。这意味着如果你有一个你不想摆脱的对象,你首先必须明确地制作它的副本。即:
other_class wantToKeepThis;
auto foo = parent(wantToKeepThis); // Doesn't compile.
auto foo = parent(std::move(wantToKeepThis)); // Object gone, don't want this.
auto foo = parent(other_class(wantToKeepThis)); // OK, copied, parent gets rvalue.
您可以尝试委托构造函数:
struct some_class : parent
{
some_class(::other_class oth) :
some_class(some_function(oth.some_property), std::move(oth))
{}
private:
some_class(const ::Foo& foo, ::other_class&& oth) :
parent(foo, std::move(oth))
{}
};
假设我们有以下代码:
struct some_class : parent
{
some_class(::other_class oth) :
parent(some_function(oth.some_property), std::move(oth))
{}
};
当然,构造会导致未定义的行为(在我的例子中是崩溃),因为 c++ 没有指定执行顺序。但是,我怎样才能在移动之前取回 属性 呢?我无法更改 parent.
创建一个辅助函数来构造可以添加排序的父级:
parent make_parent(::other_class &&oth) {
auto sf = some_function(oth.some_property);
return parent(sf, std::move(oth));
}
some_class(::other_class oth) :
parent(make_parent(std::move(oth))
{}
正如您所注意到的,问题是由于未指定的执行顺序造成的。
您可以通过使 parent
通过右值引用而不是左值获取对象来摆脱未定义的行为。这样它就获得了对现有对象的引用,并且该对象在内存中的数据实际上不会被移动。即:
struct parent {
parent (int thing, SomeProperty && some_property) { /* Do stuff. */ }
};
在这种情况下,std::move
何时在 oth
上执行并不重要。它的数据实际上不会被移动到另一个对象中,因为 parent
需要一个右值引用。因此,即使首先调用 std::move
,您的 some_function
(我假设它通过 const 左值引用获取 oth
)也将有一个合适的对象可以使用。
这里的主要缺点是父级现在总是需要右值。所以你不能在不移动它的情况下将对象传递给它。这意味着如果你有一个你不想摆脱的对象,你首先必须明确地制作它的副本。即:
other_class wantToKeepThis;
auto foo = parent(wantToKeepThis); // Doesn't compile.
auto foo = parent(std::move(wantToKeepThis)); // Object gone, don't want this.
auto foo = parent(other_class(wantToKeepThis)); // OK, copied, parent gets rvalue.
您可以尝试委托构造函数:
struct some_class : parent
{
some_class(::other_class oth) :
some_class(some_function(oth.some_property), std::move(oth))
{}
private:
some_class(const ::Foo& foo, ::other_class&& oth) :
parent(foo, std::move(oth))
{}
};