C++ 左边的右值

C++ 左边的右值,c++,c++11,rvalue,lvalue-to-rvalue,C++,C++11,Rvalue,Lvalue To Rvalue,这段代码为什么要编译?我认为ctor返回的右值不在内存中,因此不能用作左值 #include <iostream> #include <vector> class Y { public : explicit Y(size_t num = 0) : m_resource {std::vector<int>(num)} { } std::vector<int> m_resource; }; int main

这段代码为什么要编译?我认为ctor返回的右值不在内存中,因此不能用作左值

#include <iostream>
#include <vector>

class Y {
public :
    explicit Y(size_t num = 0)
    : m_resource {std::vector<int>(num)}
    {
    }

    std::vector<int> m_resource;
};

int main(int argc, const char * argv[]) {
    Y(1) = Y(0); // WHAT?!?
    return 0;
}
#包括
#包括
Y类{
公众:
显式Y(大小\u t num=0)
:m_资源{std::vector(num)}
{
}
std::向量m_资源;
};
int main(int argc,const char*argv[]{
Y(1)=Y(0);//什么?!?
返回0;
}

我不知道你从哪里得到了这个具体的经验法则。如果有的话,一条经验法则是(来自斯科特·梅耶斯):如果它有名字,它就是左值

在本例中,您将创建一个临时对象并将其传递给赋值方法/函数。这没有问题。事实上,这样做可能更有意义,比如

// Applies foo to a copy, not the original.
(Y(1) = y).foo()

诚然,
Y(*)
此处没有名称,因此它们是右值。

根据12.8[class.copy]第18段,合成赋值运算符被声明为其中之一(如果它可以合成且未被声明为删除):

  • Y&Y::operator=(Y常量&)
  • Y&Y::operator=(Y&)
    ()
也就是说,与任何其他成员函数一样,没有专门声明的成员函数也适用于右值

如果要防止在赋值的左侧出现临时对象,则需要相应地声明它:

class Y {
public :
    explicit Y(std::size_t num = 0);
    Y& operator= (Y const&) & = default;
};

标准在
=default
之前使用
&
的名称ref限定符。有关的建议是:。我不知道哪里有很好的ref限定词描述。此处有一些信息。

可以对任何对象调用成员函数
operator=
。您的代码与
Y(1)相同。运算符=(Y(0))我尝试了这个,它的工作。“=default”前面的“&”调用了什么?在哪里可以阅读更多关于这种不熟悉语法的信息?@JohnDifool。如果您在stackoverflow中搜索“ref限定符”,您应该会找到一些more@JohnDifool我的回答提到了“引用限定词”,但我同意这个非正式的名字并不是很有用,我也相应地改变了答案。C++中的入门书中找到了这个:引用限定符:用于指示可以对左值或右值调用非静态成员函数的符号。限定符&或&&&位于参数列表之后,如果有常量限定符,则位于常量限定符之后。由&限定的函数只能在左值上调用;由&&限定的函数只能在右值上调用。“我可能需要做一些挖掘来理解最后一部分的含义。在做了更多的阅读和思考之后,我仍然有一个问题,如果可以的话:您建议添加“Y&运算符=(Y const&)&=default;“有效,但这不等于说您需要默认‘合成’行为吗?换句话说,为什么它与‘默认’一起工作,而我认为它应该是‘删除’?