Pull to refresh

Концепт группировки типов в C++

Reading time2 min
Views2.9K
В статье описан способ группировки типов в языке C++, реализованный через шаблонный класс IGroup. Приём группировки типов даёт возможность указать несколько типов для объекта. Например, можно указать два интерфейса объекта.

Вообще этот приём мог быть языковой конструкцией, но таковой конструкции ни в одном ЯП не встречал (в комментариях мне уже разъяснили что почём и про Generics и про Boost и даже про STL, спасибо за обсуждение). Потому было интересно попытаться реализовать его на C++.



Предположим у вас имеются несколько интерфейсов:
1) Flyable
2) Quackable
3) Duck

Какие-то из типов будут реализовывать все эти интерфейсы разом, какие-то будут реализовывать лишь часть интерфейсов. Как указать, что некий метод работает только с объектами, умеющими летать (Flyable) и крякать (Quackable)?

Более подробно проблема описана в книге «Паттерны проектирования» (Бейтс Б., Сьерра К., Фримен Э., Фримен Э.). Ссылка на саму книгу. На сайте издателя имеется необходимый фрагмент книги с подробным описанием проблемы разделения интерфейсов.

Вашему вниманию предлагается следующий шаблон с тремя специализациями для разного числа параметров:



Использование шаблона предполагается следующим образом:

1) Для реализации группы интерфейсов:



2) Для перечисления необходимых интерфейсов в параметрах методов:



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

У описанного выше шаблонного класса IGroup есть один существенный недостаток — существенен порядок перечисления типов. Для устранения этой особенности потребуется перечислить в факториал раз больше типов в наследовании IGroup. То есть указать не все возможные сочетания типов, в количестве (N-1) из N, а их всевозможные размещения. Размещений (N-1) объектов из N возможных в (N-1)! раз больше, чем сочетаний.

Пример кода для трёх параметров:



Полный код примера приведен тут: http://codepad.org/ONI6uXjI

Конечно же, не стоит писать код для IGroup с 5-ю и 6-ю параметрами вручную — необходим скрипт для генерации этого тысячестрочного кода. Для полноценного использования не хватает работы со смартпоинтерами. Попробую на днях, но мне кажется проблем никаких при кастовании «умных» указателей не будет.

UPDATE1:
Как было верно замечено товарищами burdakovd и tangro в комментариях 1 и 2, в Java и .NET поддержка этого механизма есть в Generics. Ссылка на описание Java Generics и .NET Generics.

UPDATE2:
Пользователь susl справедливо заметил в своём комментарии, что в библиотеке Boost имеется механизм Boost Concept Check, за что ему отдельное спасибо.

UPDATE3:
Товарищ Balthasar прояснил ситуацию насчёт концептов в новом стандарте C++0x, а вернее про их отсутствие. И привёл ссылки на слайды презентации Boost Concept Check. За что ему больше спасибо!
Tags:
Hubs:
Total votes 25: ↑22 and ↓3+19
Comments82

Articles