Mik*_*ler 6 c++ compiler-construction move-semantics c++11
假设我有一个带有setter的简单类:
class MyClass
{
public:
void setName(std::string name)
{
_name = std::move(name);
}
private:
std::string _name;
};
Run Code Online (Sandbox Code Playgroud)
我在std::move
这里使用,但是如果我要省略这个并且只是写_name = name
,那么编译器是否会隐式移动name
参数,因为它不会在setter中的任何其他地方使用?它几乎可以被视为赋值表达式中的右值,因为它在其他任何地方都没有被名称引用.
编译器可以这样做吗?现有的编译器会这样做吗?
添加在什么上面纳瓦兹也说。在假设规则下,如果编译器可以证明在移动和复制之间的不同行为是不可观察的,则允许进行移动。(我相信这对于编译器来说确实很难,除了琐碎的类型之外,对于它们来说根本没有克服应对的好处。)
我不知道是否有任何编译器正在执行此操作。(我猜不会!)
AFAIK,出于重载解析的目的,将左值视为右值的唯一情况是在return语句,throw表达式和异常声明(即object
in 的声明catch (type object)
)中。此外,必须满足一些条件(基本上与复制省略相同):
当满足或将要执行复制操作的省略标准时,除非源对象是函数参数,并且要复制的对象由左值指定,选择重载构造函数的重载分辨率为首先执行,就好像该对象是由右值指定的。[...]
最后,请注意,上述情况涉及构造。它们不像OP的问题那样涵盖任务。
如果编译器能够证明这样做是安全的,那么它可能会这样做——这将是一种优化 。但这不是语言所要求的。因此,为了确保论点得到转移,你必须像你所做的那样明确地做到这一点——你在这方面无法改进。setName()