Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712

Назначение функтора

11.06.2020, 09:37. Показов 3185. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Объясните, пожалуйста, в чем выгода в использовании функтора в отличие от использования функции объекта?
Код с хабра:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
 
class SimpleFunctor {
    std::string name_;
public:
    SimpleFunctor(const char *name) : name_(name) {}
    void operator()() { std::cout << "Oh, hello, " << name_ << endl; }
 
    /* Замена оператора () */
    void print() { std::cout << "Oh, hello, " << name_ << endl; }
};
 
int main() {
    SimpleFunctor sf("catonmat");
    sf();  // выводит "Oh, hello, catonmat"
 
    sf.print(); /* делает то же самое, что и функтор */
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.06.2020, 09:37
Ответы с готовыми решениями:

Непонятное поведение функтора
Почему-то не считается произведение 1 и 6 ... #include &lt;iostream&gt; #include &lt;algorithm&gt; #include &lt;functional&gt; #include...

Отличие функтора от функции
в чём собственно отличие? имеется виду std::sort

Использование функтора в параллельных вычислениях
Имеется функтор, которых производит преобразование в потоках над элементами контейнера, например вектора. Очевидно, что использование...

17
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1819
Регистрация: 18.10.2014
Сообщений: 17,198
11.06.2020, 09:42
Цитата Сообщение от d7d1cd Посмотреть сообщение
Объясните, пожалуйста, в чем выгода в использовании функтора в отличие от использования функции объекта?
Вопрос не ясен. Никакой выгоды в этом примере нет. В обоих случаях делается одно и то же.

sf() - это просто альтернативный синтаксис вызова sf.operator (), что является обычным вызовом метода объекта, точно таким же как sf.print(). Никакой разницы в этом примере нет.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
11.06.2020, 09:56  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никакой разницы в этом примере нет.
Не удачный пример, видимо...

Попробую по-другому. Зачем может понадобиться реализовывать в классе operator(), вместо метода method()?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
11.06.2020, 10:14
Цитата Сообщение от d7d1cd Посмотреть сообщение
Зачем может понадобиться реализовывать в классе operator(), вместо метода method()?
функциональный объект нужен для того что бы его можно было вызывать как функцию, преимущество объекта в том что он может хранить внутреннее состояние. свои функциональные объекты наряду с функциями можно использовать в стандартных алгоритмах (как callback функции).
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
11.06.2020, 10:56  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
преимущество объекта в том что он может хранить внутреннее состояние
При использовании метода класса, объект тоже хранит внутреннее состояние. Нет здесь преимущества.
Может быть преимущество функционального объекта лишь в том, что он позволяет более коротко вызвать функцию?
C++
1
2
3
4
5
SimpleClass sc;
FunctObj fo;
 
sc.method();
fo(); /* Здесь просто запись короче */
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
11.06.2020, 11:10
d7d1cd, это дает возможность синтаксически использовать вызываемый объект как функцию (указатель на функцию), а значит, например, в шаблон, можно передать и указатель на функцию и вызываемый объект.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
11.06.2020, 11:15  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
значит, например, в шаблон, можно передать и указатель на функцию и вызываемый объект
Разрешите попросить Вас привести пример...
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
11.06.2020, 11:22
d7d1cd, пожалуйста Поиск по вектору
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
11.06.2020, 11:48
Цитата Сообщение от d7d1cd Посмотреть сообщение
Может быть преимущество функционального объекта лишь в том, что он позволяет более коротко вызвать функцию?
а я что тебе написал:
Цитата Сообщение от _stanislav Посмотреть сообщение
функциональный объект нужен для того что бы его можно было вызывать как функцию,
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.06.2020, 12:00
Тем, что класс становится "вызываемым" callable т.е. благодаря методу оператору () есть метод который позволяет объект класса использовать внешне как ф-цию. Ясное дело что объект класса может хранить внутри некоторое состояние
в для ф-ции это можно было бы сделать только благодаря статическими переменным и то не совсем так.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
class SimpleFunctor 
{
    int count;
public:
    SimpleFunctor() : count(0) {}
 
    void operator()() 
    { 
      std::cout << "count: " << (++count) <<  std::endl; 
   }
 };
 
int main() {
    SimpleFunctor sf;
    sf(); 
    sf();
}
Судя по всему на основе этого принципа работают лямбды.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
11.06.2020, 15:20  [ТС]
Подытожу. Если в классе, объекты которого могут быть использованы как функторы, не будет реализован operator(), но будет реализован метод functor(), то ничего не потеряется кроме наглядности кода в определенных случаях.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
11.06.2020, 15:29
Цитата Сообщение от d7d1cd Посмотреть сообщение
то ничего не потеряется кроме наглядности кода в определенных случаях.
Потеряется свойство Callable
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.06.2020, 15:39
Цитата Сообщение от d7d1cd Посмотреть сообщение
то ничего не потеряется кроме наглядности кода в определенных случаях.
По сути да.
Но как минимум тогда класс не будет работать с std алгоритмами в том виде как есть.
Для таких случаяев есть конечно лямбды. Но по своей сути лямбды те же функциональные объекте "в сахаре".
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
11.06.2020, 16:00
Цитата Сообщение от d7d1cd Посмотреть сообщение
Подытожу. Если в классе, объекты которого могут быть использованы как функторы, не будет реализован operator(), но будет реализован метод functor(), то ничего не потеряется кроме наглядности кода в определенных случаях.
если ты в своем классе не реализуешь операцию сравнения ты же не сможешь его сравнивать.

Добавлено через 27 секунд
операция вызова по сути то же самое.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1819
Регистрация: 18.10.2014
Сообщений: 17,198
11.06.2020, 17:00
Лучший ответ Сообщение было отмечено d7d1cd как решение

Решение

Цитата Сообщение от d7d1cd Посмотреть сообщение
Зачем может понадобиться реализовывать в классе operator(), вместо метода method()?
Это может понадобиться для того, чтобы иметь возможность передавать объекты вашего класса в какой-то посторонний код (алгоритм), который требует, чтобы в вашем классе поддерживался оператор ().

Посторонний алгоритм может потребовать, чтобы в вашем классе присутствовал метод print(). Тогда вам придется реализовывать в вашем классе метод print(). Посторонний алгоритм может потребовать, чтобы в вашем классе присутствовал метод vasya(). Тогда вам придется реализовывать в вашем классе метод vasya(). Посторонний алгоритм может потребовать, чтобы в вашем классе присутствовал метод operator (). Тогда вам придется реализовывать в вашем классе метод operator ().

Вот и все.

То есть никакого принципиального различия между методом print() и методом operator () нет. Вопрос только в том, чего требует тот код, который будет пользоваться вашим классом.

Традиционно, в стандартных алгоритмах для классов, использующихся в роли функциональных объектов, требуется наличие operator (). Именно через него ведется работа с такими объектами. Это делает функциональные объекты синтаксически совместимыми с обычными функциями.

Вы привели пример кода, в котором от вашего класса никто ничего не требует. Поэтому и разницы между методом print() и методом operator () он никак не иллюстриурет.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
14.06.2020, 14:11  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вопрос только в том, чего требует тот код, который будет пользоваться вашим классом.
Берем алгоритм поиска std::find. Надо в векторе элементов типа T найти нужный нам элемент. Создаем класс для использования в качестве унарного предиката.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class UnaryPredicate
{
  public:
  UnaryPredicate(const T& t) : m_t(t) {}
  bool compare(const T& t) { return t == m_t; }
 
  private:
  T m_t;
};
 
main()
{
  std::vector<T> vecT(100);
  /* Здесь наполнение вектора */
 
  UnaryPredicate up(needT);
  if (std::find_if(vecT.begin(), vecT.end(), up.compare) != vecT.end())
  {
    /* Нашел! */
  }
}
Я правильно понимаю, что здесь код up.compare не прокатит?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1819
Регистрация: 18.10.2014
Сообщений: 17,198
14.06.2020, 14:17
Цитата Сообщение от d7d1cd Посмотреть сообщение
Я правильно понимаю, что здесь код up.compare не прокатит?
Не прокатит. Отдельное up.compare - это вообще бессмысленная конструкция в С++, независимо от всего остального.

Вы можете передать в качестве предиката указатель обычную функцию (в т.ч. на статическую функцию класса), но не на метод класса.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
14.06.2020, 14:27  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы можете передать в качестве предиката указатель обычную функцию (в т.ч. на статическую функцию класса), но не на метод класса.
Спасибо. Теперь у меня есть понимание для чего может понадобиться operator()...
Еще один шажок в постижении С++
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.06.2020, 14:27
Помогаю со студенческими работами здесь

Использование собственного функтора со связывателями
Не могу правильно написать функтор, чтобы его можно было использовать с биндом. Вот пример на сравнение строк без учета регистра: ...

Создание функтора для записи в файл
По условию задачи мне нужно создать функтор который будет записывать содержимое string в файл. Конструктор функтора должен указывать объект...

Назначение оператора ::
Добрый день! Сейчас изучаю классы и в примерах часто сталкиваюсь с конструкциями типа void StringsWork::getStr() { cout...

Назначение функций
Добрый день, дана программа. #include &quot;Cipher.h&quot; #include &lt;cstdlib&gt; #include &lt;cstdio&gt; #include &lt;cmath&gt; #include...

Назначение комментария
:-|Назначение комментария. Как указать комментарий в программе С++?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru