왜 std :: string :: find ()가 실패했을 때 end iterator를 반환하지 않습니까? C ++ 컨테이너와 동작

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. 이 편리한 멤버 함수는 인덱스에서 작동합니다. 예 :

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));

답변

std::string두 가지 인터페이스 가 있기 때문입니다 .

  • 모든 컨테이너에서 발견 되는 일반 반복자 기반 인터페이스
  • std::string특정의 인덱스 기반의 인터페이스

std::string::find인덱스 기반 인터페이스의 일부 이므로 인덱스를 반환합니다.

사용하여 std::find일반 반복자 기반 인터페이스를 사용 할 수 있습니다.

std::vector<char>인덱스 기반 인터페이스를 원하지 않는 경우 사용하십시오 (이 작업을 수행하지 마십시오).