auto
可以通过以下方式提高性能避免静默隐式转换。我觉得引人注目的一个例子如下。
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
看到错误了吗?在这里,我们认为我们正在通过 const 引用优雅地获取映射中的每个项目,并使用新的 range-for 表达式来明确我们的意图,但实际上我们正在复制every元素。这是因为std::map<Key, Val>::value_type
is std::pair<const Key, Val>
, not std::pair<Key, Val>
。因此,当我们(隐含地)有:
std::pair<Key, Val> const& item = *iter;
我们必须进行类型转换,而不是获取对现有对象的引用并保留它。只要有可用的隐式转换,您就可以对不同类型的对象(或临时对象)进行常量引用,例如:
int const& i = 2.0; // perfectly OK
类型转换是允许的隐式转换,其原因与您可以转换const Key
to a Key
,但我们必须构造一个新类型的临时对象才能实现这一点。因此,我们的循环实际上是:
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
在其生命周期内)。
只需更改为:
for (auto const& item : m) {
// do stuff
}
刚刚为我们节省了大量的副本 - 现在引用的类型与初始值设定项类型匹配,因此不需要临时或转换,我们可以直接进行引用。