Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ std::map<std::string, int> use at with std::string_view

Tags:

c++

Suppose I have a std::map<std::string, int>. Is there any way to use its at method with std::string_view? Here is a code snippet :

std::string_view key{ "a" };
std::map<std::string, int> tmp;
tmp["a"] = 0;
auto result = tmp.at(key);

Here is the output I have from clang 12.0

error: no matching member function for call to 'at'

auto result = tmp.at(key);

like image 262
Dmitry Avatar asked Feb 23 '21 23:02

Dmitry


People also ask

What is std::map in C++?

std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare . Search, removal, and insertion operations have logarithmic complexity. Maps are usually implemented as red-black trees.

What is std::map used for?

If you mean std::map , it stores pairs of values. In each pair, the first value is called the key, and can be used to quickly look up the associated other value.

Is string the same as std :: string?

There is no functionality difference between string and std::string because they're the same type.

Why do we use std :: string?

std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.


2 Answers

Three things are required for something like this to happen:

  1. The map's comparator must be a transparent comparator (requires C++14, but you're already using string_view which is C++17, so this is a moot point).

  2. The at() method must have an overload that participates in overload resolution when the container has a transparent comparator.

  3. the parameter must be convertible to the map's key_type.

Neither of these are true in your example. The default std::less comparator is not a transparent comparator, there is no such overload for at(), and std::string does not have an implicit conversion from std::string_view.

There's nothing you can do about at(), however you can do something about the comparator namely using the (transparent std::void comparator), and then use find() instead of at(), which does have a suitable overload:

#include <map>
#include <string>
#include <string_view>


int main()
{
    std::string_view key{ "a" };
    std::map<std::string, int, std::less<void>> tmp;
    tmp["a"] = 0;

    auto iter=tmp.find(key);
}

More complete demo

like image 132
Sam Varshavchik Avatar answered Oct 17 '22 00:10

Sam Varshavchik


There is no implicit conversion from std::string_view to std::string, that is why you get a "no matching member function" error. See: Why is there no implicit conversion from std::string_view to std::string?

There is a std::string constructor that will accept a std::string_view as input, however it is marked as explicit, so you will have to do this instead:

auto result = tmp.at(std::string(key));

Demo

Same if you wanted to use the map's operator[] with std::string_view:

tmp[std::string(key)] = ...;
auto result = tmp[std::string(key)];
like image 21
Remy Lebeau Avatar answered Oct 17 '22 02:10

Remy Lebeau