![](/img/trans.png)
[英]Why does the std::find for vector return a iterator instead of the integer position
[英]Why does `std::string::find()` not return the end iterator on failures?
我发现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
接口臃肿且不一致,请参阅 Herb Sutter 的Gotw84关于此主题的内容。 但尽管如此, std::string::find
返回一个索引是有原因的: std::string::substr
。 这个便利成员 function 对索引进行操作,例如
const std::string src = "abcdefghijk";
std::cout << src.substr(2, 5) << "\n";
您可以实现substr
以便它接受迭代器到字符串中,但是我们不需要等待很长时间来大声抱怨std::string
不可用且违反直觉。 因此,鉴于std::string::substr
接受索引,您将如何找到上述输入字符串中第一次出现'd'
的索引,以便打印出从此 substring 开始的所有内容?
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));
这是因为std::string
有两个接口:
std::string
特定索引的接口 std::string::find
是基于索引的接口的一部分,因此返回索引。
使用std::find
使用基于通用迭代器的接口。
如果您不想要基于索引的界面(不要这样做),请使用std::vector<char>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.