2017-06-14 54 views
-1

我想知道如果使用auto或其他类似声明变量/ iterator/CallItWhatIsMoreAppropriate的东西)会每次都创建一个该项目的实例吗?一个例子会说清楚:`auto`每次都创建一个新的变量实例?

void my_fun (std::unordered_map<std::string, std::string> & my_map) { 

    std::string search_str; 

    cin >> search_str; 

    while (search_str != "something") { 

     //Does the next line create an extra overhead each time? 
     auto search = my_map.find(search_str); 

     if (search != my_map.end()) 
     { 
      std::cout << "found \n"; 

      //I should be able to modify the element inside the map here. 

     } else { 
      my_map.insert({search_str, search_str}); 
     } 

     cin >> search_str; 

    } 

} 
+0

使用'auto'没有任何开销,并且您应该始终在可以正确初始化的地方定义变量。 –

+0

@NeilButterworth我认为这是一个重要的问题,只有在需要时才声明变量,然后使用该实例,特别是声明在循环内可以运行数百万甚至数十亿次。 –

+6

“使用'auto'”在这里并不意味着什么。 'auto'只是类型名称的替代品。你真正要问的是在循环中声明一个_local变量_的后果。你的'search'是一个局部变量。这不是因为你在声明中使用了'auto';这是因为你在哪里宣布它。 –

回答

3

考虑到这个特殊的代码:

while (search_str != "something") { 

    //Does the next line create an extra overhead each time? 
    auto search = my_map.find(search_str); 

,如果你的意思是,如果有额外的开销VS:

while (search_str != "something") { 
     //Does the next line create an extra overhead each time? 
     std::unordered_map<std::string, std::string>::iterator search = my_map.find(search_str); 

没有没有区别可言,只是编译推导键入你。如果你询问是否宣布环路以外的迭代器:

std::unordered_map<std::string, std::string>::iterator search; 
    while (search_str != "something") { 
     search = my_map.find(search_str); 
     ... 

将使其更加高效,这在理论上是可能的(被碎编译器),但我几乎不怀疑会有什么。代码的可读性在这里更加重要,因为在循环中声明变量会使变量变得更清晰和更具可读性。

注意更改search键入要么const auto &要么更明确const std::unordered_map<std::string, std::string>::iterator &也不太可能使它在这种情况下更有效。

+0

如果我想对地图内的元素进行修改,我应该使用什么? (const会使它不可编辑,对吗?) –

+1

@AnnaK。你似乎误解了'std :: unordered_map :: find()'返回的内容。它不是元素本身,而是迭代器。把它看作一种指针。所以,如果你声明迭代器常量,这意味着你不能改变迭代器本身(例如使其指向另一个元素),但是这不会阻止更改它指向的元素。 – Slava

+0

感谢您向我阐明这一点。 –

2

是的。例如,使用const auto&auto&&来声明一个引用,以防你想避免创建该对象的副本。

但是,迭代器几乎没有开销,并且通常按值传递。

更重要的是,您按值传递参数my_map。按值传递将防止对该容器的任何更改从该函数外部可见(您正在编辑一个副本)。按引用传递以避免不必要的复制。

+2

'find'通过值返回一个迭代器,所以'auto&'只会创建一个绑定到临时的const引用。在这里使用'auto&'没有任何好处。编辑:实际上,它似乎甚至没有编译('非参数的无效初始化...从右值...') – Kevin

+0

@Kevin是的,我更新为使用'const auto&'。我的意图是给出一个通用的例子,而不是这个例子中的确切答案。我也明确地解释了迭代器在我的答案中最好通过value_。 – Snps

+0

为什么不用'auto &&'来代替? :) – Rakete1111

相关问题