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

Sum*_*udu 29 c++ stdstring c++-standard-library

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

例如

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

但是对于一串,

std::string myStr = "hello";
auto it = myStr.find('!');  // it == std::string::npos
Run Code Online (Sandbox Code Playgroud)

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

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

lub*_*bgr 28

To begin with, the std::string interface is well known to be bloated and inconsistent, see Herb Sutter's Gotw84 on this topic. But nevertheless, there is a reasoning behind std::string::find returning an index: std::string::substr. This convenience member function operates on indices, e.g.

const std::string src = "abcdefghijk";

std::cout << src.substr(2, 5) << "\n";
Run Code Online (Sandbox Code Playgroud)

You could implement substr such that it accepts iterators into the string, but then we wouldn't need to wait long for loud complaints that std::string is unusable and counterintuitive. So given that std::string::substr accepts indices, how would you find the index of the first occurence of 'd' in the above input string in order to print out everything starting from this substring?

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

std::cout << src.substr(std::distance(src.cbegin(), it));
Run Code Online (Sandbox Code Playgroud)

This might also not be what you want. Hence we can let std::string::find return an index, and here we are:

const std::string extracted = src.substr(src.find('d'));
Run Code Online (Sandbox Code Playgroud)

If you want to work with iterators, use <algorithm>. They allow you to the above as

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

std::copy(it, src.cend(), std::ostream_iterator<char>(std::cout));
Run Code Online (Sandbox Code Playgroud)

  • 好点子。然而,代替返回迭代器,`std :: string :: find`仍然可以返回`size()`,而不是`npos`,从而保持与`substr`的​​兼容性,同时还避免了额外的负担。 (4认同)