Асимметрия строки :: find\_first\_of и string :: find\_last\_of

С помощью функции-члена function :: find\_first\_of в стандартной библиотеке C ++ вы можете искать в пустой подстроке:

```
 s.find_first_of(c, s.size())

```

или

```
s.find_first_of(c, string::npos)

```

Но вы не можете искать в пустой подстроке с помощью  `string :: find_last_of` ; следующий вызов будет искать в подстроке, содержащей (только) первый символ:

```
 s.find_last_of(c, 0)

```

Я думаю, что это несовершенство стандартной библиотеки C ++, не так ли?

Здесь я не вижу никакой асимметрии. На самом деле все наоборот, оно выглядит совершенно симметричным. Подумайте о  `find_first_of`  в качестве поиска в  *right*  из некоторой исходной позиции, а  `find_last_of`  - это поиск в  *left*  с некоторой начальной позиции.

Имя  `find_last_of`  имеет обманчивое качество: оно подразумевает естественный поиск  *forward* , за исключением того, что мы возвращаем последнее вхождение вместо первого. Однако с двунаправленными последовательностями можно игнорировать «форвардную» природу имени и думать о нем как о  *обратном*  поиске. Обратный поиск также возвращает первое вхождение, он просто переходит из  *влево*  из начальной точки. С этой точки зрения функция симметрична с помощью  `find_first_of` .

**EDIT:** After reading your comments I finally understand your point. So, the problem is that the current semantics of `pos` parameter makes it impossible to specify *empty* search region for `find_last_of`. Yes, that makes sense. I agree, that is indeed something that can be seen as inconsistency in `find_last_of` design. 

Для целей согласования я действительно ожидал бы  `find_last_of`  не включительно в отношении значения  `pos` . В этом случае спецификация целевой позиции  `xpos` , возвращаемая  `find_last_of` , будет

> 
> xpos < pos and xpos < size();
> 
> 
> 

В этом случае  `s.find_last_of (c, 0)`  будет искать пустой префикс, а  `s.find_last_of (c, s.size ())`  будет искать всю строку.

Однако стандарт говорит

> 
> xpos <= pos and xpos < size();
> 
> 
> 

Я действительно не знаю, почему они решили указать параметр  `pos`  такой инклюзивный смысл. Вероятно, они думали, что это облегчит понимание.



Здесь я не вижу никакой асимметрии. На самом деле все наоборот, оно выглядит совершенно симметричным. Подумайте о  `find_first_of`  в качестве поиска в  *right*  из некоторой исходной позиции, а  `find_last_of`  - это поиск в  *left*  с некоторой начальной позиции.

Имя  `find_last_of`  имеет обманчивое качество: оно подразумевает естественный поиск  *forward* , за исключением того, что мы возвращаем последнее вхождение вместо первого. Однако с двунаправленными последовательностями можно игнорировать «форвардную» природу имени и думать о нем как о  *обратном*  поиске. Обратный поиск также возвращает первое вхождение, он просто переходит из  *влево*  из начальной точки. С этой точки зрения функция симметрична с помощью  `find_first_of` .

**EDIT:** After reading your comments I finally understand your point. So, the problem is that the current semantics of `pos` parameter makes it impossible to specify *empty* search region for `find_last_of`. Yes, that makes sense. I agree, that is indeed something that can be seen as inconsistency in `find_last_of` design. 

Для целей согласования я действительно ожидал бы  `find_last_of`  не включительно в отношении значения  `pos` . В этом случае спецификация целевой позиции  `xpos` , возвращаемая  `find_last_of` , будет

> 
> xpos < pos and xpos < size();
> 
> 
> 

В этом случае  `s.find_last_of (c, 0)`  будет искать пустой префикс, а  `s.find_last_of (c, s.size ())`  будет искать всю строку.

Однако стандарт говорит

> 
> xpos <= pos and xpos < size();
> 
> 
> 

Я действительно не знаю, почему они решили указать параметр  `pos`  такой инклюзивный смысл. Вероятно, они думали, что это облегчит понимание.