我偶然发现一个赋值操作符返回的不是引用,而是一个副本,它可以作为一种解决方法,以便在STL容器中存储const
成员的对象。
class Test_class
{
public:
int const whatever;
explicit Test_class(int w) : whatever(w) {}
// note the missing &
Test_class operator=(Test_class const& rhs) {
return Test_class(rhs.whatever);
}
};
vector<Test_class> vec;
Test_class foo(42);
vec.push_back(foo);
assert(vec[0].whatever == 42);
这段代码感觉非常奇怪,但是gcc编译它并且它似乎正常工作。
那么陷阱在哪里?
修改
事实上,在push_back()
vec[0].whatever
之后,添加了一个断言用于说明。
修改
感谢您的回答!只是为了它的乐趣,这个版本运行得很好;)
void operator=(Test_class const&) {
throw 42;
}
答案 0 :(得分:3)
标准或编译器不强制执行操作符重载的大多数公认实践。这只是对行为的期望。您可以在此处查看部分内容:Operator overloading或此处:http://en.cppreference.com/w/cpp/language/operators。
这里的缺陷是你的operator=
实际上并不是一个赋值算子。请考虑以下代码:
Test_class a(15);
Test_class b(20);
a = b;
通常,在执行此代码后,您希望a.whatever
为20,但它仍然是15。
C ++ 03要求向量元素既可以复制,也可以复制,编译器可以自由选择使用的内容。在C ++ 11中,它们只需要是可复制构造的(或可移动构造的),因此不需要赋值赋形符。
答案 1 :(得分:0)
你实际上并没有在这里指定任何东西。你甚至可以将赋值运算符声明为const
,因为它什么都不做。
Test_class a(17);
Test_class b(33);
a = b; // nothing happens.
operator =的返回值并不重要,我通常将其声明为void
。只有你做a = b = c;
之类的事情才有意义,这不常见。使用你的operator=
这将编译,但再一次,什么都不做。