如何使用auto获得const_iterator
How do I get a const_iterator using auto?
第一个问题:是否有可能"强迫";a const_iterator
使用auto?例如:
std::map<std::string, int> usa;
//...init usa
auto city_it = usa.find("New York");
我只是想查询,而不是改变city_it
指向的任何东西,所以我想让city_it
成为map<int>::const_iterator
。但是通过使用auto, city_it
与map::find()
的返回类型相同,即map<int>::iterator
。任何建议吗?
对不起,但我只是认为最好的建议是不使用auto
,因为你想执行(隐式有效)类型转换。auto
用于推导精确类型,这不是您在这里想要的。
就这样写:
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
正如MooingDuck正确指出的那样,使用类型别名可以提高代码的可读性和可维护性:
typedef std::map<std::string, int> my_map;
my_map::const_iterator city_it = usa.find("New York");
从c++ 17开始,你可以这样使用std::as_const
:
#include <utility>
// ...
auto city_it = std::as_const(usa).find("New York");
一个干净的解决方案是使用const引用来指向其他可修改的映射:
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
这将确保你不能修改const_usa
,并将使用const迭代器。
与@Jollymorphic的答案相比,这并不是一个完全不同的转换到const
的方法,但我认为有一个像这样的实用程序一行函数是很方便的:
template<class T> T const& constant(T& v){ return v; }
这使得转换更吸引人的眼睛:
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");
嗯,我得说,并不总是越大越好。当然,您可以根据自己的喜好选择函数的名称——as_const
或仅const_
都是可能的选择。
另一个使用auto的变体(同时保留可变usa和const usa):
map<std::string, int> usa;
//...init usa
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
如果你不需要在init之后的map是可变的,还有一些其他的选择。
你可以定义USA为const,并通过函数调用初始化它:
const map<std::string, int> usa = init_usa();
auto city_it = usa.find("New York");
或使用lambda初始化const map:
const auto usa = [&]()->const map<std::string, int>
{
map<std::string, int> usa;
//...init usa
return usa;
}();
auto city_it = usa.find("New York");
在c++ 11中,可以这样做:
decltype(usa)::const_iterator city_it = usa.find("New York");
我现在不能测试这个,但我想它会成功的:
auto city_it = const_cast< const map<int> & >(usa).find("New York");
你可以使用auto来"跟踪"一个类型或"推断"一个类型:
// deduce
auto city_it = usa.find("New York");
// track
auto city_it = std::map<int>::const_iterator( usa.find("New York"));
另外,watch是Herb Sutter的现代c++风格演讲,涵盖了这些类型演绎的大部分指导。https://youtu.be/xnqTKD8uD64