2011-08-18 34 views
7

我正在学习STL这些天,我想知道如果STL容器返回引用是否所有的STL容器都通过引用返回它们的元素?

e.g:

vector.first(); 
map[key]; 
*vector.begin(); 
Or any possible return that ends with element (or value type) of container 

e.g:

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 

这是所有容器的情况?或者有几点需要考虑,我没有展示?

+0

“例如”?你怎么看“例如”手段?如果外国单词混淆,为什么不使用英语?例如“例如”和“另一个例子”? –

+0

我发现问题很不清楚。 “如果所有的STL容器都按照引用返回” - 那应该是什么意思?首先,你应该说“标准库容器”。其次,谁回来了?您是否有一套特定的成员功能?或者你是否在询问关于*不能通过引用返回的成员函数? (像'pop_back()'?) –

+0

@Kerrek:我修正了例如作为“例如”是多余的。对于未来的访客:http://ancienthistory.about.com/od/abbreviations/f/ievseg.htm – 2011-09-16 12:33:48

回答

13

以安全方式返回添加的元素或容器成员函数中的容器是不可能的。 STL容器大多提供“有力保证”。返回操作元素或容器将无法提供强有力的保证(它只会提供“基本保证”)。有关这些条款的解释请参见助推网站Exception-Safety in Generic Components。从Boost's website看下面。

  • 基本保证:该组件的不变量被保留,并没有资源泄漏。
  • 有力的保证:该操作已成功完成或抛出异常,使程序状态与操作开始之前完全相同。
  • 无丢包保证:该操作不会抛出异常。

返回主题:根据此previous SO answer,背后的原因是,返回的东西可能会调用可能会引发异常的复制构造函数。但功能已经退出,所以成功完成了它的主要任务,但仍然抛出了一个例外,这是违反强有力的保证。你可能会想:“那么让我们参考回来!”,虽然这听起来像是一个很好的解决方案,但它也不完全安全。考虑下面的例子:

MyClass bar = myvector.push_back(functionReturningMyClass()); // imagine push_back returns MyClass& 

不过,如果复制赋值操作符抛出,我们不知道的push_back成功与否,从而间接地违反了强有力的担保。尽管这不是直接违反。当然,使用MyClass& bar = //...可以解决这个问题,但是如果有人忘记&,容器可能会进入不确定状态,这很不方便。

一个非常类似的推理是因为std::stack::pop()不返回弹出的值。而是top()以安全的方式返回最高值。在调用top之后,即使在复制构造函数或复制赋值构造函数抛出时,您仍然知道堆栈没有变化。

+0

我对强力保证一无所知:(如果你能用简单的话来解释一下这个属性,我很乐意,谢谢 –

+1

@ Mr.Anubis:看我的编辑 – 2011-08-18 15:12:25

2

容器(序列,关联)的所有类型旨在提供一致的界面(在可能的情况下)。它使得学习它们相对容易,并且使用它们更容易(只要你已经学会了它们;))

因此,例如,所有容器的operator[]将返回对实体索引的引用(在关联容器,它将首先被创建)。对于序列容器,这提出了一个关于边界检查的有趣点 - 但这是一个不同的故事。同样,如果您采取其他常见操作(如insert等)将会有类似的界面。您最喜欢的参考资料通常会提供您需要的所有信息。

2

是的stl容器的超载[]运算符返回一个引用。因此,在上面的示例中,melements中的值将被更改。

http://www.cplusplus.com/reference/stl/vector/operator%5B%5D/

的定义或操作符[]为向量是:

reference operator[] (size_type n); 
const_reference operator[] (size_type n) const; 

在哪里会员类型referenceconst_reference是参考的类型的载体容器中的元素(通常定义为在大多数存储分配模型中分别为T&const T&)。

编辑:请注意,并非所有stl容器都有超载的[]运算符。那些不是:list, multimap,multiset, priority_queue,queue, setstack

+1

注意到这一点也很重要'std :: map'的'operator []'没有'const'重载,因为如果key不存在,它必须插入到map中。如果'const'ness是 –

+0

valarrays不完全正确,非const版本返回一个引用,而const版本返回一个副本。 – wxffles

1

std::vector<bool>被允许返回除bool参考以外的其他内容(假设您确实是指标准库,而不是SGI STL)。但它通常也被认为是不应该被称为容器的错误。

相关问题