在使用C++中的std::string_view时,如何与std::map<std::string, int>结合使用?

5
假设我有一个 std::map<std::string, int>。是否可以使用它的 at 方法与 std::string_view 一起使用?下面是代码片段:
std::string_view key{ "a" };
std::map<std::string, int> tmp;
tmp["a"] = 0;
auto result = tmp.at(key);

这是来自clang 12.0的输出:

错误:调用'at'的成员函数无匹配项

auto result = tmp.at(key);


哦,我使用clang出现了“没有匹配的成员函数可调用”的错误... - Dmitry
@Dmitry,你启用了C++17吗? - Tony
是的,甚至包括使用cmake的c++17。 - Dmitry
1
@TonyTannous std::string_view 在 C++17 中被引入。 - Remy Lebeau
@RemyLebeau 好的,谢谢你提供的链接 - 现在我明白我缺少什么了。 - Dmitry
显示剩余6条评论
2个回答

8

要发生这样的事情需要三个条件:

  1. 地图的比较器必须是透明比较器(需要C++14,但您已经使用了C++17的string_view,因此这是一个无意义的点)。

  2. at()方法必须具有参与重载分辨率的重载形式,当容器具有透明比较器时。

  3. 参数必须可转换为地图的key_type

在您的示例中,这些条件都不成立。默认的std::less比较器不是透明比较器,没有at()的这种重载形式,并且std::string没有从std::string_view进行隐式转换。

关于at(),您无法做任何事情,但是您可以对比较器采取一些措施即使用(透明的std::void比较器),然后使用具有合适重载形式的find()代替at()

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

更完整的演示


3

没有从std::string_viewstd::string的隐式转换,这就是为什么会出现“没有匹配的成员函数”错误。详情请见:为什么没有从std::string_view到std::string的隐式转换?

有一个接受std::string_view作为输入参数的std::string构造函数,但它被标记为explicit,因此您需要执行以下操作:

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

演示

如果您想要使用映射的operator[]std::string_view

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接