这些天我正在学习STL,我想知道STL容器是否通过引用返回?
例如:
vector.first();
map[key];
*vector.begin();
Or any possible return that ends with element (or value type) of container
Run Code Online (Sandbox Code Playgroud)
例如:
std::vector<int> elements;
elements.push_back(20);
elements[0]=60; // this will also change the value
elements.front() = 23; // even the functions also behave same way like subscript operator
Run Code Online (Sandbox Code Playgroud)
这是所有容器的情况吗?还是有一些要考虑的问题我没有表现出来?
小智 13
无法以安全的方式返回添加的元素或容器成员函数中的容器.STL容器大多提供"强有力的保证".返回操纵元素或容器将使得不可能提供强有力的保证(它只提供"基本保证").这些术语的解释在boost的网站上提供了通用组件中的异常安全性.请参阅Boost网站的以下内容.
回到主题:根据之前的SO回答,其背后的原因是,返回一些东西可能会调用一个复制构造函数,这可能会抛出异常.但是这个功能已经退出,所以它成功地完成了它的主要任务,但仍然抛出异常,这违反了强有力的保证.你可能会想:"好吧,然后让我们参考!" 虽然这听起来像是一个很好的解决方案,但它也不是非常安全.考虑以下示例:
MyClass bar = myvector.push_back(functionReturningMyClass()); // imagine push_back returns MyClass&
Run Code Online (Sandbox Code Playgroud)
但是,如果复制赋值运算符抛出,我们不知道push_back是否成功,从而间接违反了强保证.即使这不是直接违规.当然使用MyClass& bar = //...相反会修复这个问题,但是容器可能进入不确定状态会非常不方便,因为有人忘记了&.
一个非常类似的推理背后std::stack::pop()是不返回弹出值的事实.而是top(以安全的方式返回最顶层的值.在调用top之后,即使复制构造函数或复制赋值构造函数抛出,您仍然知道堆栈没有改变.