左边的右值
rvalue on the left side
为什么要编译这段代码?我认为 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;
}
不确定您是从哪里获得该特定经验法则的。如果有的话,一个经验法则是(来自 Scott Meyers):如果它有一个名字,它就是一个左值。
在这种情况下,您要创建一个临时对象并将其传递给一个赋值 method/function。这没有问题。事实上,这样做甚至可能有意义,如
// Applies foo to a copy, not the original.
(Y(1) = y).foo()
的确 Y(*)
在这里没有名字,因此它们是右值。
根据 12.8 [class.copy] 第 18 段,合成赋值运算符被声明为其中之一(如果它可以被合成并且未被声明为已删除):
Y& Y::operator=(Y const&)
Y& Y::operator=(Y&)
()
也就是说,与任何其他未用 ref-qualifiers 明确声明的成员函数一样,它适用于右值。
如果你想阻止赋值左边的临时对象,你需要相应地声明它:
class Y {
public :
explicit Y(std::size_t num = 0);
Y& operator= (Y const&) & = default;
};
标准对 = default
之前的 &
使用名称 ref-qualifier。相关提案为N2439. I don't know where there is a good description of ref-qualifiers. There is some information at this question.
为什么要编译这段代码?我认为 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;
}
不确定您是从哪里获得该特定经验法则的。如果有的话,一个经验法则是(来自 Scott Meyers):如果它有一个名字,它就是一个左值。
在这种情况下,您要创建一个临时对象并将其传递给一个赋值 method/function。这没有问题。事实上,这样做甚至可能有意义,如
// Applies foo to a copy, not the original.
(Y(1) = y).foo()
的确 Y(*)
在这里没有名字,因此它们是右值。
根据 12.8 [class.copy] 第 18 段,合成赋值运算符被声明为其中之一(如果它可以被合成并且未被声明为已删除):
Y& Y::operator=(Y const&)
Y& Y::operator=(Y&)
()
也就是说,与任何其他未用 ref-qualifiers 明确声明的成员函数一样,它适用于右值。
如果你想阻止赋值左边的临时对象,你需要相应地声明它:
class Y {
public :
explicit Y(std::size_t num = 0);
Y& operator= (Y const&) & = default;
};
标准对 = default
之前的 &
使用名称 ref-qualifier。相关提案为N2439. I don't know where there is a good description of ref-qualifiers. There is some information at this question.