2014-12-02 51 views
1

假设我有一个名为Foo的类,它具有合适的移动构造函数/赋值运算符。鉴于以下伪代码:C++ 11是否使用移动语义进行复制到分配优化?

Foo some_func(Foo var) { 
    <update var> 
    return var; 
} 

int main() { 
    Foo var; 
    var = some_func(var); 
} 

请问C++ 11时,通过向VAR some_func,并再次重新分配给无功,因为变种的原始值将被销毁反正自动使用移动语义?我想认为这是一个安全的优化,它可以让你编写与传递引用/指针一样快的纯函数。如果它不能这样做,为什么不呢?我知道它可以强制std :: move,但它会很酷,如果它是自动的。

+1

这种优化 - 将局部变量'var'移动到函数参数 - 如果它具有可观察的副作用,则是非法的。例如,如果移动构造'some_func'或'some_func'本身的参数本身,则'main'中的局部变量可能会被修改/处于无效状态。 – dyp 2014-12-02 18:22:39

+0

这是一个很好的答案,尽管它似乎过于谨慎。我很难想出一个可能会抛出的非人为的移动构造函数。 – 2014-12-02 18:34:33

+2

@gct即使移动构造函数有时也需要内存分配,并且内存分配总是可以抛出。 – hvd 2014-12-02 18:55:27

回答

5

威尔C++ 11传递到变种时some_func自动使用移动语义,

不,那是一个拷贝构造,因为var是一个左值。

该语言不允许编译器执行其他操作。只有当一个左值被隐式移动而不是被复制时,才从函数返回,例如,这条线在some_func将使用移动构造函数:

return var; 

,并再次重新分配给无功,因为变种的原始值将被销毁反正?

这将使用Foo的移动赋值运算符,因为它将一个右值赋给var

你会避免任何副本,如果你使用some_func(std::move(var))或者如果你这样写这个:

Foo var = some_func({}); 

这将创建一个临时的哪个初始化函数的参数,然后返回函数的参数,将使用一招,那么var将被移动建造,但移动可以被消除。因此,编译器只允许为函数参数执行默认构造,并为var移动构造。

+0

我相当肯定你不能从函数参数中复制/移动。 – 2014-12-02 19:03:48

+0

@ T.C。哎呀,你是对的 - 参数可以被看作是一个右值而不是左值来选择构造函数,但是它不能被忽略。我会纠正这一点。 – 2014-12-02 19:05:33

相关问题