在迭代基本类型时使用const引用的任何缺点? [英] Any disadvantage of using const reference when iterating over basic types?

查看:142
本文介绍了在迭代基本类型时使用const引用的任何缺点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现自己越来越多地使用C ++ 11,在过去我将使用迭代器,现在我使用 range-based for loops

I find myself using C++11 more and more lately, and where I would have been using iterators in the past, I now am using range-based for loops whenever possible:

std::vector<int> coll(10);
std::generate(coll.begin(), coll.end(), []() { return rand(); } );

C ++ 03:

for (std::vector<int>::const_iterator it = coll.begin(); it != coll.end(); ++it) {
   foo_func(*it);
}

C ++ 11:

for (auto e : coll) { foo_func(e); }

但是如果集合元素类型是模板参数怎么办? foo_func()可能会被重载以通过const引用传递复杂(=昂贵的复制)类型,以及简单的值:

But what if the collection element type is a template parameter? foo_func() probably will be overloaded to pass complex (= expensive to copy) types by const reference, and simple ones by value:

foo_func(const BigType& e) { ... };
foo_func(int e) { ... };



我在使用C ++ 03风格代码时没有给出这么多想法以上。我将以相同的方式迭代,并且由于解引用一个const_iterator产生一个const引用,一切都很好。但是使用C ++ 11基于范围的for循环,我需要使用一个const引用循环变量来获得相同的行为:

I didn't give this much thought while I was using the the C++03-style code above. I would iterate the same way, and since dereferencing a const_iterator produces a const reference, everything was fine. But using the C++11 range-based for loop, I need to use a const reference loop variable to obtain the same behavior:

for (const auto& e : coll) { foo_func(e); }

突然我不知道了,如果这不会引入不必要的汇编指令如果 auto 是一个简单类型(例如实现引用的幕后指针)。

And suddenly I wasn't sure anymore, if this wouldn't introduce unnecessary assembly instructions if auto was a simple type (such as a behind-the-scene pointer to implement the reference).

但编译一个示例应用程序确认没有简单类型的开销,这似乎是在模板中使用基于范围的循环的通用方法。如果不是这样, boost :: call_traits :: param_type

But compiling a sample application confirmed that there is no overhead for simple types, and that this seems to be the generic way to use range-based for loops in templates. If this hadn't been the case, boost::call_traits::param_type would have been the way to go.

问题:标准中是否有任何保证?

Question: Are there any guarantees in the standard?

(我意识到这个问题并不真正与基于range的for循环有关,使用const_iterators时也存在)。

(I realize that the issue is not really related to range-based for loops. It's also present when using const_iterators.)

推荐答案

标准容器都从它们的迭代器返回引用(注意,然而,一些容器不是真正的容器,例如 std :: vector< bool> 它返回一个代理)。其他迭代器可能返回代理或值,虽然这不是严格支持。

The standard containers all return references from their iterator (note, however, that some "containers aren't really container, e.g., std::vector<bool> which returns a proxy). Other iterators might return proxies or values although this isn't strictly supported.

当然,标准不作任何保证任何类型的性能相关特性(超出复杂性保证)都被认为是实现的质量。

Of course, the standard doesn't make any guarantees with respect to performance. Any sort of performance related feature (beyond complexity guarantees) are considered to be quality of implementation.

也就是说,你可能需要考虑让编译器选择:

That said, you might want to consider having the compiler make the choice for you as it did before:

for (auto&& e: coll) { f(e); }

这里的主要问题是 f()可能会收到一个非 - const 引用。如果需要,可以使用 coll const 版本来防止此情况。

The main issue here is that f() may receive a non-const reference. This can be prevented if necessary using a const version of coll.

这篇关于在迭代基本类型时使用const引用的任何缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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