Как имитировать несуществующую функцию find_first_not_of?

Шаблон класса std::basic_string имеет функции-члены find_first_of и find_first_not_of.

Заголовок <algorithm>, однако, содержит только общий find_first_of.

Вопрос1: Является ли отсутствие

std::find_first_not_of(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)

просто недосмотр (как, например, copy_if), или он намеренно опущен, поскольку поведение может быть достигнуто с помощью другой стандартной функции?

Конечно, я мог бы написать свой собственный find_first_not_of, но

Question2: Есть ли готовое обходное решение где-то в <algorithm>? Например, отсутствие copy_if компенсируется наличием remove_copy_if

Заранее спасибо

Ответ 1

У меня была такая же проблема, короткий ответ на ваш вопрос: это невозможно со стандартными библиотеками stl (хотя это возможно с boost:: phoenix).

Однако вы можете написать собственное закрытие, окружающее итераторы последовательности, которые принимают параметризованную переменную "Значение" и возвращает результат bool.

 template<class Iterator> struct is_not_in_range
{
    Iterator const begin;
    Iterator const end;
is_not_in_range(Iterator const& b, Iterator const& e)
    :   begin(b)
    ,   end(e) {}
    template<class Value> bool operator()(Value & v)
    {
          return std::find(begin,end,v) == end;
    }
};

Тогда вы можете сделать это

std::find_if(begin1, end1,  is_not_in_range<Iterator2>(begin2,end2));

В качестве альтернативы вы можете написать версию, которая использует меньшее разветвление, но требует break- > continue (аппроксимируется оператором goto)

template<class Iterator1, class Iterator2> Iterator1 find_first_not_of
(   Iterator1 const& begin1
,   Iterator1 const& end1
,   Iterator2 const& begin2
,   Iterator2 const& end2 )
{
    for(Iterator1 mid1 = begin1; mid1 != end1; ++mid1)
    {
        for(Iterator2 mid2 = begin2; mid2 != end2; ++mid2)
            if(*mid1 == *mid2)
                goto FOUND;
        return mid1;
FOUND:      ;
    }
    return end1;
};

Ответ 2

В последнем STL добавлены новые функции (Перейти к).

all_of, any_of, none_of, find_if_not, copy_if и т.д.

Ответ 3

Я не уверен в вашем первом вопросе, но думаю, что лучше всего вы можете найти find_if:

template <class Iter>
class Check
{
public:
    Check(Iter first, Iter last) : first_(first), last_(last) { }
    template <class T>
    bool operator()(const T& item) { return std::find(first, last, item) == last; }
private:
    Iter first_;
    Iter last_;
};

find_if(first1, last1, Check<Iter2>(first2, last2));

Ответ 4

Легко написать одно:

pos = std::find(search_list.begin()...)
if (pos!= npos)
{
   pos = std::find(black_list.begin()...)
   if (pos!= npos)
   {
       continue search
   }
   else
  {
      found !!
  }
}
else
{
   not found
}