繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM