为什么operator ++返回非const值?

sky*_*ain 23 c++ const return-value

我读过Scott Meyers编写的Effective C++ 3rd Edition.

本书的第3项" const尽可能使用",如果我们想要防止rvalues被意外地分配给函数的返回值,那么返回类型应该是const.

例如,增量函数iterator:

const iterator iterator::operator++(int) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,防止了一些事故.

iterator it; 

// error in the following, same as primitive pointer
// I wanted to compare iterators
if (it++ = iterator()) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

但是,std::vector::iteratorGCC中的迭代器不返回const值.

vector<int> v;
v.begin()++ = v.begin();   // pass compiler check
Run Code Online (Sandbox Code Playgroud)

这有什么理由吗?

Pup*_*ppy 11

我很确定这是因为它会对rvalue引用和任何类型的攻击造成严重破坏decltype.尽管这些功能不在C++ 03中,但已知它们即将到来.

更重要的是,我不相信任何标准函数返回const rvalues,它可能是在标准发布之后才考虑的事情.此外,const rvalues通常不被认为是Right Thing To Do™.并非所有非const成员函数的使用都是无效的,并且返回的const rvalues正在全面阻止它们.

例如,

auto it = ++vec.begin();
Run Code Online (Sandbox Code Playgroud)

是完全有效的,实际上是有效的语义,如果不是完全可取的话.考虑我提供方法链的类.

class ILikeMethodChains {
public:
    int i;
    ILikeMethodChains& SetSomeInt(int param) {
        i = param;
        return *this;
    }
};
ILikeMethodChains func() { ... }
ILikeMethodChains var = func().SetSomeInt(1);
Run Code Online (Sandbox Code Playgroud)

这是否应该被禁止,因为有时候,我们可能会调用一个没有意义的功能?不,当然不.或者"互换互惠"怎么样?

std::string func() { return "Hello World!"; }
std::string s;
func().swap(s);
Run Code Online (Sandbox Code Playgroud)

如果func()生成一个const表达式,这将是非法的- 但它完全有效,并且实际上,假设该std::string实现没有在默认构造函数中分配任何内存,快速且易读/可读.

你应该意识到的是C++ 03 rvalue/lvalue规则坦率地说没有意义.它们实际上只是部分烘焙,并且在允许一些可能的权利的同时,最低限度要求禁止一些明显的错误.C++ 0x rvalue规则更加完善完善.

  • @davka:不,他们只是不能绑定到非常量引用。它们本身在任何方面都不是常量。 (2认同)