How do I get a const_iterator using auto?

C++C++11Auto

C++ Problem Overview


First question: is it possible to "force" a const_iterator using auto? For example:

map<int> usa;
//...init usa
auto city_it = usa.find("New York");

I just want to query, instead of changing anything pointed by city_it, so I'd like to have city_it to be map<int>::const_iterator. But by using auto, city_it is the same to the return type of map::find(), which is map<int>::iterator. Any suggestion?

C++ Solutions


Solution 1 - C++

Sorry, but I just think the best suggestion is not using auto at all, since you want to perform a (implicitly valid) type conversion. auto is meant for deducing the exact type, which is not what you want here.

Just write it this way:

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

As correctly pointed out by MooingDuck, using type aliases can improve the readability and maintainability of your code:

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

Solution 2 - C++

Since C++17 you can use std::as_const like this:

#include <utility>

// ...

auto city_it = std::as_const(usa).find("New York");

Solution 3 - C++

A clean solution is to work with a const reference to the otherwise modifiable map:

const auto &const_usa = usa;
auto city_it = const_usa.find("New York");

This will make sure you can't modify const_usa, and will use const iterators.

Solution 4 - C++

This isn't a drastically different take on conversion to const in comparision to @Jollymorphic's answer, but I think that having a utility one-liner function like this is handy:

template<class T> T const& constant(T& v){ return v; }

Which makes the conversion much more appealing to the eye:

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");

Well, I'd say, bigger isn't always better. You can of course choose the name of the function according to your preferences - as_const or just const_ are possible alternatives.

Solution 5 - C++

Another variation using auto (keeping both a mutable usa and a const usa):

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

If you don't need the map to be mutable at all after init there are some other options.

you can define usa as const and init it with a function call:

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

or using a lambda to init a 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");

Solution 6 - C++

In C++11, you can do this:

decltype(usa)::const_iterator city_it = usa.find("New York");

Solution 7 - C++

I'm not in a position to test this right now, but I think it'll do the trick:

auto city_it = const_cast< const map<int> & >(usa).find("New York");

Solution 8 - C++

You can use auto to "track" a type or "deduce" a type: // deduce auto city_it = usa.find("New York");

// track auto city_it = std::map<int>::const_iterator( usa.find("New York"));

Also, watch is modern c++ style talks by Herb Sutter, which covers most of these type deductions guidance. https://youtu.be/xnqTKD8uD64

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvirtualPNView Question on Stackoverflow
Solution 1 - C++Andy ProwlView Answer on Stackoverflow
Solution 2 - C++jhasseView Answer on Stackoverflow
Solution 3 - C++rustyxView Answer on Stackoverflow
Solution 4 - C++XeoView Answer on Stackoverflow
Solution 5 - C++ChetSView Answer on Stackoverflow
Solution 6 - C++snips-n-snailsView Answer on Stackoverflow
Solution 7 - C++JollymorphicView Answer on Stackoverflow
Solution 8 - C++Sid SarasvatiView Answer on Stackoverflow