问题描述
我明白为什么 C++11 中的 auto
类型提高了正确性和可维护性.我读过它也可以提高性能(几乎总是Auto by Herb Sutter),但我错过了一个很好的解释.
I can see why the auto
type in C++11 improves correctness and maintainability. I've read that it can also improve performance (Almost Always Auto by Herb Sutter), but I miss a good explanation.
auto
如何提高性能?- 谁能举个例子?
推荐答案
auto
可以通过避免静默隐式转换来提高性能.我认为引人注目的一个例子如下.
auto
can aid performance by avoiding silent implicit conversions. An example I find compelling is the following.
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
看到错误了吗?在这里,我们认为我们通过常量引用优雅地获取地图中的每个项目并使用新的 range-for 表达式来明确我们的意图,但实际上我们正在复制每个元素.这是因为 std::map::value_type
是 std::pair
,而不是 std::pair
密钥,Val>
.因此,当我们(隐式)有:
See the bug? Here we are, thinking we're elegantly taking every item in the map by const reference and using the new range-for expression to make our intent clear, but actually we're copying every element. This is because
std::map<Key, Val>::value_type
is std::pair<const Key, Val>
, not std::pair<Key, Val>
. Thus, when we (implicitly) have:
std::pair<Key, Val> const& item = *iter;
我们必须进行类型转换,而不是引用现有对象并将其保留在那里.只要有可用的隐式转换,您就可以对不同类型的对象(或临时对象)进行 const 引用,例如:
Instead of taking a reference to an existing object and leaving it at that, we have to do a type conversion. You are allowed to take a const reference to an object (or temporary) of a different type as long as there is an implicit conversion available, e.g.:
int const& i = 2.0; // perfectly OK
类型转换是允许的隐式转换,原因与您可以将
const Key
转换为 Key
的原因相同,但我们必须构造一个新类型的临时对象为了做到这一点.因此,我们的循环实际上是:
The type conversion is an allowed implicit conversion for the same reason you can convert a
const Key
to a Key
, but we have to construct a temporary of the new type in order to allow for that. Thus, effectively our loop does:
std::pair<Key, Val> __tmp = *iter; // construct a temporary of the correct type
std::pair<Key, Val> const& item = __tmp; // then, take a reference to it
(当然,实际上并没有
__tmp
对象,它只是为了说明,实际上未命名的临时对象只是在其生命周期内绑定到 item
).
(Of course, there isn't actually a
__tmp
object, it's just there for illustration, in reality the unnamed temporary is just bound to item
for its lifetime).
只需更改为:
for (auto const& item : m) {
// do stuff
}
刚刚为我们节省了大量的副本——现在引用的类型与初始化类型匹配,所以不需要临时或转换,我们可以直接引用.
just saved us a ton of copies - now the referenced type matches the initializer type, so no temporary or conversion is necessary, we can just do a direct reference.
这篇关于使用 C++11 的“自动"能提高性能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!