2017-07-26 84 views
0

今天我发现这个代码不工作,因为我期望它的工作。 根据我对L值的知识,应该调用复制构造函数,而对于R值,应该选择移动构造函数。否则,std::move的目的实际上什么都不做,只能投射到R值。我期待return obj将调用复制构造函数,但它调用移动。 我知道这里的副本是无用的,但这是关于规则的。如果我的拷贝构造函数有副作用,那就是我的情况(我知道它不应该,但从技术上说它可以 - 例如:std :: cout调用)。 有没有什么标准允许这种行为?另外我怎样才能强制复制?移动构造函数返回而不是复制

#include <iostream> 

class X 
{ 
public: 
    X() = default; 

    X(const X& r): i(r.i) 
    { 
     std::cout << "copy ctor" << std::endl; 
    } 

    X(const X&& r): i(r.i) 
    { 
     std::cout << "move ctor" << std::endl; 
    } 
    int i = 0; 
}; 

X foo() 
{ 
    X obj; 
    obj.i = 10; 
    return obj; 
} 

int main() 
{ 
    X x = foo(); 
} 

移动构造函数

移动构造函数

回答

1

cppreference(重点煤矿):

如果[返回的表达]是一个左值表达式和所要求的条件除了[返回的表达式]命名函数参数th之外,复制elision被满足或将被满足en重载解析选择用于初始化返回值的构造函数执行两次:第一个就像[返回的表达式]是一个右值表达式(因此它可以选择移动构造函数或参考const的复制构造函数) ,如果没有合适的转换可用,则第二次使用lvalue [返回的表达式]执行重载解析(因此它可以选择引用非const的复制构造函数)。 上述规则适用,即使该函数的返回类型为类型不同[返回式(复制省略需要同一类型)

长话短说,return隐含试图打动你回什么让当感。它只会作为最后的手段进行复制(例如,不提供移动构造函数)。

+0

它实际上很奇怪,它可能默默地复制,如果你明确要求移动,并可能移动,如果你没有:) – incognito

+0

谢谢你的解释 – incognito

+0

@incognito的确。这就是为什么你应该仔细设计你的课程;) – Quentin