[我发现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
与其他容器相比有些特殊,所以我想知道这背后是否有真正的原因。(令人惊讶的是,我找不到任何人在任何地方对此进行质疑)。
[首先,众所周知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));