Как я могу инвертировать функтор в C++ (STL)?

вы можете использовать array_replace(), но он работает не по значению, а по положению, и array_replace() возвращает новый массив, а не изменяет исходный.

вы можете изменить другую часть вашего кода, как показано ниже, так как вы не использовали измененный массив;

 ....
 ....
 else
 {
  $replace = array($i => "300");
  $arr2 = array_replace($arr, $replace);
  var_dump($arr2);//this holds the replaced array
 }
14
задан Andre 5 November 2008 в 14:15
поделиться

4 ответа

Лучшее решение состоит в том, чтобы использовать STL функциональная библиотека. Путем получения предиката из unary_function<SomeType, bool> , Вы затем сможете использовать not1 функция, которая делает точно, в чем Вы нуждаетесь (т.е. отрицание унарного предиката).

Вот то, как Вы могли сделать это:

struct FindPredicate : public unary_function<SomeType, bool>
{
    FindPredicate(const SomeType& t) : _t(t) {}

    bool operator()(const SomeType& t) const {
      return t == _t;
    }

private:
    const SomeType& _t;
};

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
    return find_if(v.begin(), 
                   v.end(), 
                   not1(FindPredicate(valueToFind))) == v.end();
}

Если Вы хотите к решению для самокрутки (который является, по моему скромному мнению, не наилучший вариант...), ну, в общем, Вы могли записать другой предикат, который является отрицанием первого:

struct NotFindPredicate
{

    NotFindPredicate(const SomeType& t) : _t(t) {
    }
    bool operator()(SomeType& t) {
      return t != _t;
    }

private:
    const SomeType& _t;
};

bool AllSatisfy(std::vector<SomeType>& v) {
    return find_if(v.begin(), 
                   v.end(), 
                   NotFindPredicate(valueToFind)) == v.end();
}

Или Вы могли добиться большего успеха и записать шаблонный инвертор функтора, как:

template <class Functor>
struct Not
{
    Not(Functor & f) : func(f) {}

    template <typename ArgType>
    bool operator()(ArgType & arg) { return ! func(arg); }

  private:
    Functor & func;
};

то, что Вы могли использовать следующим образом:

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
    FindPredicate f(valueToFind);
    return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end();
}

Конечно, последнее решение лучше, потому что можно снова использовать Не структуру с каждым функтором, который Вы хотите.

20
ответ дан 1 December 2019 в 09:13
поделиться

Посмотрите функтор библиотеки станд. not1, он возвращает функтор, который является логическим не того, что функтор Вы даете ему, возвратился бы.

Необходимо смочь сделать что-то как:

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) {
    return find_if(v.begin(), v.end(), not1(FindPredicate(valueToFind))) != v.end();
}
7
ответ дан 1 December 2019 в 09:13
поделиться

В первый раз я использовал not1 Я задался вопросом, почему это просто не назвали not.

Ответ удивил меня немного (см. комментарий).

2
ответ дан 1 December 2019 в 09:13
поделиться

Поскольку Вы используете его, Вам не нужен функтор FindPredicate, с тех пор в примере Вы только тестируете равенство.

bool all_equal(std::vector<SomeType>& v, SomeType& valueToFind)
{
   return v.end() == find_if(v.begin(), v.end(), std::bind1st (equal_to (), valueToFind) );
}

bool all_not_equal( std::vector<SomeType>& v, SomeType &valueToFind ) {
{
   return v.end() == find_if(v.begin(), v.end(), std::bind1st (not_equal_to (), valueToFind) );
}

И Вы могли просто сделать это шаблоном отдельно.

template< typename InputIterator , typename Predicate >
bool test_all( InputIterator first, InputIterator last, Predicate pred )
{
  return last == find_if( first, last, pred );
}

test_all( v.begin(), v.end(), std::bind1st( not_equals_to_( value )) );
0
ответ дан 1 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: