Что такое мультиметод обычно объясняется на одном классическом примере. Вот у нас есть иерархия неких фигур.
struct Shape {...};
struct Square : Shape {...};
struct Triangle : Shape {...};
И надо уметь строить их пересечение.
bool overlap( Square& a, Triangle& b) {...}
bool overlap( Triangle& a, Square& b) {...}
bool overlap( Shape& a, Square& b) {...}
bool overlap( Square& b, Shape& a) {...}
И хочется, чтобы можно было определить функцию вроде
bool overlap( virtual Shape& a, virtual Shape& b);
При вызове которой автомагически бы выбирался нужный из вариантов overlap.
Формальное определение этого всего: "механизм мультиметодов - механизм вызова виртуальных функций на базе более чем одного объекта".
В своей книге "Дизайн и Эволюция С++" (13.8) Страуструп рассказывает, что очень хотел бы, чтобы мультиметоды были в С++, но вот как-то не сложилось. И в С++09 тоже не сложится, похоже. Предложения по мультиметодам они задвинули куда-то далеко. Вот официальные бумаги по этим предложениям раз и два. (все примеры кода взяты оттуда, кстати)
Мультиметоды можно сделать с использованием RTTI и dynamic_cast'ов. Например вот так: Multiple Dispatch. A new approach using templates and RTTI. Там не все так просто, потому что хочется, чтобы не нужно было делать двойную работу и чтобы не нужно было переписывать куски кода в случае появления новых фигур.
Можно обойтись без RTTI и dynamic_cast'ов. Например как здесь: MultiMethods in C++: Finding a complete solution. Код получается довольно тяжелый. По мне так лучше с RTTI.
Про мультиметоды много и загрузочно можно почитать у Александреску в "Современном проектирование на С++". Глава 11. Она так и называется "Мультиметоды".
Ссылки по теме:
Multiple dispatch - статья в Википедии
4 коммент.:
Ах вот, что это такое... Как только стала понятна суть, я пошел нашел, как это делается в Питоне, вдруг кому интересно будет. Способ от создателя Питона Five-minute Multimethods in Python.
Вкратце это работает так. В основе все то же определение типа в духе "if это Rectangle and это Circle: вызывать это". Но поскольку это Питон, там можно получить программный доступ не только к типам, но и к имени функции, и к процессу ее "компиляции". Поэтому вместо написания руками здоровенного if нужные функции помечаются некой аннотацией, и функция при создании во-первых регистрируется в map'е со всеми типами своих параметров, а во вторых на ее место в коде подставляется вызывальщик, который будет эти параметры проверять :-).
Вот. Нам не надо ждать, пока язык расширят :-)
Да чего тут сравнивать с питоном, питон, как динамический язык, в таких вещах на стотыщ очков впереди :)
Я смотрю из языков со статической типизацией multiple dispatch только Nice поддерживает. И то у меня есть очень субъективное такое предчуствие что в таких языках от этого больше граблей чем пользы.
Подумалось мне, что можно и без "загрузочного" Александреску ;) обойтись, смотрю
Meyers, "More effective C++" - и точно, Item 31 "Making functions virtual with respect to more than one object."
Разные способы, подробно, но без загруза ;)
Для того, чтобы понять что такое настоящие мультиметоды, надо в первую очередь посмотреть на CLOS - Common Lisp Object System. Вот там можно изменить поведение любого класса не затрагивая его кода напрямую. а пре- и пост- методы, это вообще просто праздник какой-то :-)
Отправить комментарий