为什么编译器允许C++中的vector.begin()= vector.end()?

Ant*_*Ant 8 c++ vector std

在学习C++中的迭代器时,我尝试了以下方法:

#include <vector>

int main() {
    std::vector<int> a;
    a.end()=a.begin();
    //Why is this even allowed by the compiler?
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Vla*_*cow 10

如果例如函数end将返回指针,那么它将不可用.

例如,不会编译此代码

int a[] = { 1, 2, 3 };

std::end( a ) = std::begin( a );
Run Code Online (Sandbox Code Playgroud)

GCC发出错误

error: lvalue required as left operand of assignment
  std::end( a ) = std::begin( a );
                ^
Run Code Online (Sandbox Code Playgroud)

但是,当使用类类型的对象时,它们可以调用ovetloaded复制(或移动)赋值运算符.

所以问题出现了为什么函数不返回常量迭代器对象.我认为可以申请operator ++.例如

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

对于直接访问迭代器作为指针,您可以简单地编写

auto it = begin( a ) + 1;
Run Code Online (Sandbox Code Playgroud)


M.M*_*M.M 7

标准未指定std::vector::iterator是类类型还是原始指针.

如果它是类类型,则此代码调用operator=返回的临时对象a.end().不是一个非常有用的操作,但合法.(Rvalues可能有调用它们的函数).

如果你的库std::vector::iterator是一个指针,那么这个代码将无法编译,因为简单的赋值需要左边的左值.

Jarod42指出,如果迭代器的赋值运算符被定义为:

std::vector::iterator& std::vector::iterator::operator =(std::vector::iterator) &;
Run Code Online (Sandbox Code Playgroud)

那么这段代码就是非法的; 尾随&意味着只有在左值上调用该函数时才能选择该函数.

但是没有这样定义,我猜想委员会不想因为没有充分理由而使一些法律法规成为非法; 也许有一个用例,没人想到.