std::set的迭代器通过解引用返回的key为什么不能被移动走?

我们尝试从某个c++编译器实现的标准库进行分析:
typename std::set::iterator的定义如下:
屏幕快照 2020-03-08 上午11.32.40.png

来看__base的const_iterator:
屏幕快照 2020-03-08 上午11.33.41.png

这就是真正的iterator类,看它的接引用运算符重载:
屏幕快照 2020-03-08 上午11.34.33.png

返回值reference的类型:
屏幕快照 2020-03-08 上午11.35.45.png
是一个const value_type&类型,带有const限定符。

对这样类型的对象进行std::move()操作并不会使得const属性消失,而会得到const value_type&&类型的对象,这个对象不能被非常量的右值引用所绑定,而只能被常量左值引用绑定。
因此避免了触发move而触发了copy。
例子:

std::set s;
s.push(2);
auto tmp = std::move(*s.begin()); // copy , not move.

以上,虽然为了保证逻辑的完整,const T&& 能够绑定到常量的右值,但不建议重载以此类型为参数类型的函数,对方声明为const,及意味着不想被修改,所以不要移动它。

void func(const int&& i) {
    std::cout << "1";
}

void func(const int& i) {
    std::cout << "2";
}

调用func(2),会输出1,即对于右值(无论是常量的还是非常量的)来说,常量右值引用的匹配优先级高于常量左值引用。

你可能感兴趣的:(c++,c++11)