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

Viewed 519

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

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

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)];
Related