如何使用auto获取const_iterator?

vir*_*lPN 52 c++ auto c++11

第一个问题:是否有可能"强迫" const_iterator使用汽车?例如:

map<int> usa;
//...init usa
auto city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

我只是想查询的不是改变的任何东西指出,city_it,所以我想有city_itmap<int>::const_iterator.但是通过使用auto,city_it返回类型是相同的map::find(),也就是说map<int>::iterator.有什么建议吗?

And*_*owl 36

抱歉,我认为最好的建议根本就没有使用auto,因为你想要执行(隐式有效)类型转换.auto用于推断确切的类型,这不是你想要的.

只需这样写:

std::map<std::string, int>::const_iterator city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

正如MooingDuck正确指出的那样,使用类型别名可以提高代码的可读性和可维护性:

typedef std::map<std::string, int> my_map;
my_map::const_iterator city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

  • 或者,如果由于任何晦涩的原因,有人讨厌typedef,那么仍然有`decltype(usa.cbegin())it = ...`;) (5认同)
  • @ us2012:是的,那会有效,但我无法在`cbegin()`和`cend()之间做出决定:-D开玩笑吧 (2认同)

Xeo*_*Xeo 12

转换到const与@ Jollymorphic的答案相比,这并不是一个完全不同的转换,但我认为拥有像这样的实用单行函数是很方便的:

template<class T> T const& constant(T& v){ return v; }
Run Code Online (Sandbox Code Playgroud)

这使得转换对眼睛更具吸引力:

auto it = constant(usa).find("New York");
// other solutions for direct lengths comparision
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
auto city_it = const_cast<const std::map<std::string, int>&>(usa).find("New York");
Run Code Online (Sandbox Code Playgroud)

好吧,我会说,更大并不总是更好.您当然可以根据自己的喜好选择功能名称 - as_const或者只是const_可能的选择.

  • c ++ 17已将std :: as_const添加到标题<utility> [link](http://en.cppreference.com/w/cpp/utility/as_const) (6认同)
  • @GMan:`make_x`对我来说意味着******************************这就是我选择`as_const`的原因,它改变了对象上的*view*. (2认同)

jha*_*sse 10

从C ++ 17开始,您可以这样使用std::as_const

#include <utility>

// ...

auto city_it = std::as_const(usa).find("New York");
Run Code Online (Sandbox Code Playgroud)


rus*_*tyx 7

一个干净的解决方案是使用const引用到其他可修改的映射:

const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

这将确保您无法修改const_usa,并将使用const迭代器.


Che*_*etS 6

使用auto的另一种变体(保持可变的美国和const美国):

map<std::string, int> usa;
//...init usa
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

如果你在init之后根本不需要地图可变,那么还有一些其他的选择.

你可以将usa定义为const并使用函数调用来初始化它:

const map<std::string, int> usa = init_usa();
auto city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)

或使用lambda初始化const映射:

const auto usa = [&]()->const map<std::string, int> 
   {
   map<std::string, int> usa;
   //...init usa
   return usa;
   }();
auto city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)


sni*_*ils 6

在 C++11 中,您可以这样做:

decltype(usa)::const_iterator city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)