Перейти к содержанию
Посмотреть в приложении

A better way to browse. Learn more.

Форум Академгородка, Новосибирск

A full-screen app on your home screen with push notifications, badges and more.

Чтобы установить это приложение на iOS и iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
Чтобы установить это приложение на Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Замыкания в C++

  • Ответов 75
  • Просмотры 13,8 тыс
  • Создана
  • Последний ответ

Топ авторов темы

Рекомендуемые сообщения

Опубликовано
лучше приведите пример алгоритма, паттерна или чего-нибудь, что без замыканий реализовать намного труднее, чем с ними, и код становится более читаемый, переиспользуемый и т.д.
Во-первых, определите что значит «намного труднее». А то, может, для вас и в машинных кодах не намного труднее писать, с чего ради с вами тогда спорить?

намного труднее, значит намного труднее

не лично для меня, а в терминах какой-либо метрики трудоемкости, или на личном опыте проекта

либо просто должно быть очевидно из примера, что с замыканиями хорошо

 

Т.е. опять же зачем тогда с вами спорить :)?

я не спорю, я хочу интересные примеры замыканий от любителей всяких излишеств

 

Listener намного лучше таки выглядит без замыканий, пишется это немного медленнее, но зато сопровождать и переиспользовать такой код проще, о чем и было вышесказано

 

Опубликовано

Можно и пример: паттерн команда в случае наличия лямбд и замыканий - тривиален и не требует какого-либо дополнительного кодирования, т.к. замыкани - это и есть команда. :)

То жэ самое с Listener/Observer как указал AmbassadorKosh.

 

Лямбды обычно применяют для "небольших" настроек существующих функций, поэтому их вполне можно оставлять без комментариев - кода мало и он прозрачен.

Примр: сортировка списка по нескольким полям.

python

res = sorted(lst, key=lambda obj: (obj.fld1, obj.fld2, obj.fld3))

haskell

-- В стандартной библиотеке нет функции сортировки по ключу - сделаем. :)
sortFrom getKey = sortBy (\x y -> compare (getKey x) (getKey y))

res = sortFrom (\obj -> (fld1 obj, fld2 obj, fld1 obj)) lst

 

Опубликовано
Можно и пример: паттерн команда в случае наличия лямбд и замыканий - тривиален и не требует какого-либо дополнительного кодирования, т.к. замыкани - это и есть команда. :)

То жэ самое с Listener/Observer как указал AmbassadorKosh.

 

В копилку к Observer, простые [stateless] КА, где, как минимум конфигурацию, как предикатов переходов, так и действий, выполняемых для переходов, довольно удобно описывать лямбдами.

Опубликовано
Можно и пример: паттерн команда в случае наличия лямбд и замыканий - тривиален и не требует какого-либо дополнительного кодирования, т.к. замыкани - это и есть команда. :)

То жэ самое с Listener/Observer как указал AmbassadorKosh.

приведите примеры кода, пожалуйста

Опубликовано
приведите примеры кода, пожалуйста

 

Here, take this, eh kills aleins and doesn't afraid of anything...

 

BTW, http://c2.com/cgi/wiki?CommandPattern

Опубликовано
приведите примеры кода, пожалуйста

Чем не устраивают примеры Observer-а из википедии?

Сначала идёт портянка на Java, а потом пример на Python с лямбдами. :)

 

Или, давай ты запостишь сюда не очень большой свой код реализации Listener/Observer, а я перепишу его c использованием лямбд и замыканий. :)

Опубликовано
приведите примеры кода, пожалуйста

Чем не устраивают примеры Observer-а из википедии?

Сначала идёт портянка на Java, а потом пример на Python с лямбдами. :)

 

Или, давай ты запостишь сюда не очень большой свой код реализации Listener/Observer, а я перепишу его c использованием лямбд и замыканий. :)

с Listener все более менее понятно

твои лямбды для сортировок выглядят и правда хорошо (пока размер передаваемой функции небольшой, и все очевидно, я думаю с Listener та же ситуация)

 

замыкани - это и есть команда"

лучше приведи пример простейшей команды на замыканиях (без лямбд)

 

fiend, зачем ты меня посылаешь на... в гугл?

лучше приведи пример по КА

Опубликовано
лучше приведи пример простейшей команды

 

listener слушающий ровно одно событие это по сути и есть команда (как в анекдоте: выливаем из чайника воду...).

 

на замыканиях (без лямбд)

 

постановка не понятна.

 

 

 

 

Опубликовано
твои лямбды для сортировок выглядят и правда хорошо (пока размер передаваемой функции небольшой, и все очевидно, я думаю с Listener та же ситуация)

Лямбды и должны быть маленькими, чтобы оставался понятен смысл всего выражения.

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

 

лучше приведи пример простейшей команды на замыканиях (без лямбд)

 

Берём пример из википедии и перетанцовываем на python один в один:

class Switch(object):
  'the Invoker class' 

  __flipUpCommand = None
  __flipDownCommand = None

  def __init__(self, flipUpCmd, flipDownCmd):
    super(Switch, self).__init__()
    self.__flipUpCommand = flipUpCmd;
    self.__flipDownCommand = flipDownCmd;

  def flipUp(self):
    self.__flipUpCommand()

  def flipDown(self):
    self.__flipDownCommand()

class Light(object):
  'Receiver class'
  def turnOn(self):
    print "The light is on"

  def turnOff(self):
    print "The light is off"

def main():
  'The test class or client'
  from sys import argv

  lamp = Light();
  switch = Switch(lamp.turnOn, lamp.turnOff);

  def usage():
    print '%s [ ON | OFF ]' % argv[0]

  action = {
    'ON' : switch.flipUp,
    'OFF': switch.flipDown,
  }.get(argv[1].upper() if len(argv) > 1 else '', usage)

  action()

В данном случае в lamp.turnOn, lamp.turnOff, switch.flipUp, switch.flipDown - это замыкание методов на конкретный экземпляр

Внутри usage - замыкание внешней переменной argv

 

Т.е. Command и его производные оказались ненужны вовсе.

Опубликовано

круто :)

C++:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
using namespace boost;

class Light {
public:
void turnOn() {
	cout << "The light is on" << endl;
}
void turnOff() {
	cout << "The light is off" << endl;
}
};

typedef function<void()> Command;

int main(int argc, char* argv[]) {
Light light;	
Command lightOnCmd = bind(&Light::turnOn, &light);
Command lightOffCmd = bind(&Light::turnOff, &light);	
// test commands
lightOnCmd();
lightOffCmd();
return 0;
}

 

замыкание метода на объект и правда полезно

это ж почти один к одному C# delegate/event (не считая цепочки вызовов)

 

Опубликовано

Там вроде предполагалось, что Switch таки несёт какую-то полезную нагрузку, кроме вызовов команд - вот я его и не выкинул. :)

Иначе можно было и Light соптимизировать - оставить только собственно сам вывод в cout. :)

 

А так да - bind удобен в простых случая. Ещё и ограниченную поддержку лямбд даёт. К тому же входит в следующий стандарт и уже сейчас может использоваться в gcc 4.2 и выше. :)

 

И делегаты в шарпе - тот же тип функционального объекта.

 

Так что, как не крути, а замыкания, лямбды и функциональные типы уже давно в майстриме. :)

 

П.С. А Linq - это списковые дополнения + монады - тоже гольное ФП.

Так что кто там ещё думает что кодит на чистом ООП? :)

Опубликовано

Да, небольшие КА в python-е часто рисуются на замыканиях:

class FSM(object):
  def start_state(self, smb):
    self.do_start_state(...)
    return {
      smb2: self.state2,
      smb3: self.state3,
    }.get(smb)

  def state2(self, smb):
    self.do_state2(...)
    return {
      smb2: self.state2,
      smb3: self.state3,
    }.get(smb)

  def state3(self, smb):
    self.do_state3(...)
    return {
      smb2: self.state2,
      smb3: self.state3,
    }.get(smb)

  def run(self, smb_iter):
    state = self.start_state
    for smb in smb_iter:
      state = state(smb)
      if not state:
        break

Опубликовано

Tonal

Что то вроде списковых дополнений в с# было до linq, например в List<> классе.

Тогда появились анонимные делегататы и замыкания.

 

List<MyClass> list = GetSomeList();

 

string maxFullName = "";

 

list

.FindAll(delegate bool (MyClass o)

{

return o.Address.IndexOf("Morskoy") >= 0;

})

.ConvertAll(delegate string (MyClass o)

{

return o.FirstName + " " + o.LastName;

}).

ForEach(delegate (string fullName)

{

if (fullName > maxFullName) maxFullName = fullName;

});

 

linq немного более продвинутая технология. Language integrated query, это ведь просто запрос, найти что то по таким то условиям, преобразовать в то то. Select, from, where. Имеется аналогия с sql по ключевым словам, но ведь sql это наверное structured query language, а смысл этой фразы не подразумевает однозначно реляционного вида данных. MS реализовала linq to sql и linq to xml, структура которого есть дерево. Не ms реализации linq to ... есть почти к чему угодно наверное, (linq to google подойдет?) разве что качество их под вопросом.

linq to sql для FireBird кажется есть, но не MS.

Кроме того в linq части запроса это объекты которые можно использовать, передавать куда то вовне и тп.

 

Лямбды наверное из за linq и появились в c# Вместе с Expressions, анонимными классами, методами-расширениями..

Опубликовано

Tonal

Хотя наверное Linq в применениии к скажем List<> это действительно просто списковое дополнение. Но удобное :)

Опубликовано

Не совсем по теме замыканий и лямбд, но все же. Вслед имплементациям паттернов команда. Классика жанра на java или c# со Spring.

Модуль логики:

interface ILight {..}

class UltravioletLight : ILight {имплементация}

 

модуль UI:

каркас:

interface ICommand {void execute();}

interface IController {Dictionary<string, ICommand> CommandTable {get;set;}}

 

class Controller : IController {имплементация}

 

включение обращений к логике в каркас UI:

class LightOnCommand : ICommand { public ILight Light {set{..}} .. имплементация ICommand использующая Light}

class LightOfCommand : ICommand { public ILight Light {set{..}} .. имплементация ICommand ..}

 

 

конфигурация конейнера (в xml файле):

<object id="MyLight" class="UltravioletLight"/>

 

<object id="MyLightOn" class="LightOnCommand ">

<property name="Light" ref=MyLight />

</object>

 

<object id="MyLightOff" class="LightOfCommand ">

<property name="Light" ref=MyLight />

</object>

 

<object id="MyController" class="Controller">

<property name="CommandTable">

<dictionary>

<add key="ON" ref=MyLightOn/>

<add key="OFF" ref=MyLightOff/>

</dictionary>

</property>

</object>

 

майн:

main(argv)

{

((IController)Ioc["Controller"]).Table[argv[0]].execute();

}

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

Аккаунт

Навигация

Поиск

Поиск

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.