赋值运算符返回值类型

时间:2014-01-21 12:52:46

标签: c++

我偶然发现一个赋值操作符返回的不是引用,而是一个副本,它可以作为一种解决方法,以便在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;
}

2 个答案:

答案 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=这将编译,但再一次,什么都不做。