STL容器函数返回值 [英] STL container function return values

查看:111
本文介绍了STL容器函数返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当查看STL容器的成员函数时,我发现了一个奇怪的想法。为什么不像 std :: vector< T> :: push_back(T)这样的函数没有可选的返回值(迭代器甚至是对附加对象的引用)?我知道 std :: string 函数 insert 和 erase 返回迭代器,但这是明显的原因。我认为它通常会保存第二行代码,经常跟随这些函数调用。

When looking over the member functions of the STL containers, an odd thought occurred to me. Why don't functions like std::vector<T>::push_back(T) not have an (optional) return value (iterator or even a reference to the appended object)? I know std::string functions like insert and erase return iterators, but that's for obvious reasons. I'd think it'd often save a second line of code that often follows these function calls.

我相信C ++的设计师有一个很好的理由,请启发我:)

I'm sure the designers of C++ have a very good reason, please enlighten me :)

UPDATE :我在这里包含一个真实世界的代码示例,它可以减少代码长度:

UPDATE: I'm including a real-world code example here where it could reduce code length:

if( m_token != "{" )
{
    m_targets.push_back( unique_ptr<Target>(new Dough(m_token)) );
    return new InnerState( *(m_targets.back()), this );
}

可以减少到

if( m_token != "{" )
    return new InnerState( *(m_targets.push_back( unique_ptr<Target>(new Dough(m_token)) )), this );

如果我假设 std :: list :: push_back 返回对添加的元素的引用。代码有点重,但是由于 unique_ptr 的构造函数和取消引用它,大多数(两个括号)。也许为了清楚一个版本没有任何指针:

If I assume std::list::push_back returns a reference to the added element. The code is a bit heavy, but that's mostly (two sets of parentheses) due to unique_ptr's constructor and dereferencing it. Perhaps for clarity a version without any pointers:

if( m_token != "{" )
{
    m_targets.push_back( Dough(m_token) );
    return new InnerState( m_targets.back(), this );
}

vs。

if( m_token != "{" )
    return new InnerState( m_targets.push_back( Dough(m_token) ), this );


推荐答案

返回添加的元素,功能不可能以安全的方式。 STL容器主要提供强力保证。返回操作元件或容器将使得不可能提供强有力的保证(它将仅提供基本保证)。
这背后的原因是,返回的东西可能会调用一个复制构造函数,可能会抛出异常。但是功能已经退出,所以它成功地完成了它的主要任务,但仍然抛出异常,这是对强有力的保证的违反。你可能会想:那么让我们回来参考!,虽然这听起来像一个很好的解决方案,它不是完全安全。考虑下面的例子:

Returning the added element, or the container in container member functions is not possible in a safe way. STL containers mostly provide the "strong guarantee". Returning the manipulated element or the container would make it impossible to provide the strong guarantee (it would only provide the "basic guarantee"). The reason behind this is, that returning something could possibly invoke an copy-constructor, which may throw an exception. But the function already exited, so it fulfilled its main task successfully, but still threw an exception, which is a violation of the strong guarantee. You maybe think: "Well then lets return by reference!", while this sounds like a good solution, its not perfectly safe either. Consider following example:

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

仍然,如果拷贝赋值操作符抛出,我们不知道push_back是否成功,违反强有力的保证。即使这不是直接违反。当然使用 MyClass& bar = //...而是会解决这个问题,但是会很不方便,容器可能进入不确定的状态,只是因为有人忘了一个&

Still, if the copy-assignment operator throws, we dont know if push_back succeded or not, thus indirectly violating the strong-guarantee. Even though this is not a direct violation. Of course using MyClass& bar = //... instead would fix this issue, but it would be quite inconvenient, that a container might get into an indeterminate state, just because someone forgot a &.

很相似推理是因为 std :: stack :: pop()不返回弹出的值。而 top()以安全的方式返回最高的值。在调用top之后,即使一个拷贝构造函数或一个拷贝赋值构造函数抛出,你仍然知道栈没有改变。

A quite similar reasoning is behind the fact that std::stack::pop() does not return the popped value. Instead top() returns the topmost value in a safe way. after calling top, even when a copy-constructor, or a copy-assignment constructor throws, you still know that the stack is unchanged.

em>
我相信为新添加的元素返回一个迭代器应该是完全安全的,如果迭代器类型的复制构造函数提供了无throw保证(和我知道的)。

I believe returning an iterator for the newly added element should be perfectly safe, if the copy-constructor of the iterator-type provides the no-throw guarantee (and every i know of does).

这篇关于STL容器函数返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆