Как передать функцию-член для каждого цикла? - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь использовать std::for_each() вместо обычного цикла for в качестве практики, но я не могу передать функцию-член for_each().

Вот код:

class Class
{
    public :
        void func (int a)
        {
            cout << a * 3 << " ";
        }
}ob1;

int main()
{
    int arr[5] = { 1, 5, 2, 4, 3 };
    cout << "Multiple of 3 of elements are : ";
    for_each(arr, arr + 5, ob1);
}

Работает, только если эта функция-член void operator() (int a). Я не знаю, почему любая другая функция-член не может быть передана в for_each()!

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Функция for_each имеет несколько перегрузок, которые можно увидеть здесь .

C++ - std::for_each - Algorithm библиотека

Определено в заголовке algorithm

template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f ); 
// (1) (until C++20)  

template< class InputIt, class UnaryFunction >
constexpr UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f ); 
// (1) (since C++20)  

template< class ExecutionPolicy, class ForwardIt, class UnaryFunction2 >
void for_each( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryFunction2 f ); 
// (2)  (since C++17)  
  • 1) Применяет данный функциональный объект f к результату разыменования каждого итератора в диапазоне [first, last) по порядку.
  • 2) Применяет данный функциональный объект f к результату разыменования каждого итератора в диапазоне [first, last) (не обязательно по порядку). Алгоритм выполнен в соответствии с политикой. Эта перегрузка не участвует в разрешении перегрузки, если std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> верно.

Для обеих перегрузок, если iterator type равно mutable, f может изменить elements от range до dereferenced iterator. Если f возвращает результат, результат игнорируется.

В отличие от остальных алгоритмов, for_each не разрешено делать копии elements в последовательности, даже если они trivially copyable.


Параметры

первый , последний -

  • диапазон применения функции к

полис -

  • политика выполнения для использования. См. Политику выполнения для деталей.

f -

  • объект функции, который будет применен к результату разыменования каждого итератора в диапазоне [first, last)
  • Подпись функции должна быть эквивалентна следующей:
  • void fun(const Type &a);
  • Подпись не обязательно должна иметь const &.
  • Тип Type должен быть таким, чтобы объект типа InputIt мог быть разыменован, а затем неявно преобразован в Type.

Требования к типу


Это говорит вам обо всех требованиях, которые необходимы для ваших predicate, function object или functor, которые необходимы для удовлетворения условий, необходимых для последнего параметра for_each. Если вы не хотите, чтобы все классы или пользовательские структуры данных определяли operator(), вы можете написать универсальный функтор, который будет реализовывать operator() для вашего класса (классов), или вы можете использовать lambda. Вы можете обратиться к ответу Реми Лебо для деталей реализации

0 голосов
/ 09 января 2019

Вы не передаете никакой метод класса for_each(), вы передаете объект, который работает, только когда объект реализует operator().

Чтобы for_each() вызывал ваш Class::func() метод, вам нужно:

  • реализовать operator() в вашем классе:

    class Class
    {
    public:
        void func (int a)
        {
            std::cout << a * 3 << " ";
        }
    
        void operator()(int a)
        {
            func(a);
        }
    }ob1;
    
    std::for_each(arr, arr + 5, ob1);
    
  • используйте отдельный делегат, который реализует operator() для вызова в ваш класс.

    • вы можете определить пользовательский функтор (до C ++ 11):

      struct functor
      {
          Class &obj;
      
          functor(Class &c) : obj(c) {}
      
          void operator()(int a)
          {
              obj.func(a);
          }
      };
      
      std::for_each(arr, arr + 5, functor(ob1));
      
    • или используйте std::bind() (C ++ 11 и более поздние версии):

      #include <functional>
      
      auto func = std::bind(&Class::func, &obj1, std::placeholders::_1);
      std::for_each(arr, arr + 5, func);
      
    • или используйте лямбда (C ++ 11 и более поздние версии):

      auto func = [&](int a){ obj1.func(a); };
      std::for_each(arr, arr + 5, func);
      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...