为什么std :: string :: find()在失败时不会返回结束迭代器

问题描述 投票:6回答:1

[我发现std::string::find的行为与标准C ++容器不一致。

例如

std::map<int, int> myMap = {{1, 2}};
auto it = myMap.find(10);  // it == myMap.end()

但是要输入一个字符串,

std::string myStr = "hello";
auto it = myStr.find('!');  // it == std::string::npos

为什么失败的myStr.find('!')不返回myStr.end()而不是std::string::npos

由于std::string与其他容器相比有些特殊,所以我想知道这背后是否有真正的原因。(令人惊讶的是,我找不到任何人在任何地方对此进行质疑)。

c++ std stdstring
1个回答
1
投票

[首先,众所周知std::string界面be肿且不一致,请参见Herb Sutter的Gotw84关于此主题。但是,尽管如此,在std::string::find返回索引:std::string::substr的背后有一个原因。此便利成员函数对索引进行操作,例如

const std::string src = "abcdefghijk";

std::cout << src.substr(2, 5) << "\n";

您可以实现substr以便它接受字符串中的迭代器,但是这样,我们就不必等待很长时间就抱怨std::string不可用且违反直觉。因此,考虑到std::string::substr接受索引,您如何在上述输入字符串中找到'd'首次出现的索引,以便打印出从此子字符串开始的所有内容?

const auto it = src.find('d'); // imagine this returns an iterator

std::cout << src.substr(std::distance(src.cbegin(), it));

这也可能不是您想要的。因此,我们可以让std::string::find返回一个索引,这里是:

const std::string extracted = src.substr(src.find('d'));

如果要使用迭代器,请使用<algorithm>。他们允许您进入以上]

auto it = std::find(src.cbegin(), src.cend(), 'd');

std::copy(it, src.cend(), std::ostream_iterator<char>(std::cout));
© www.soinside.com 2019 - 2024. All rights reserved.