- PVSM.RU - https://www.pvsm.ru -
Использовать шаблонные шаблонные параметры С++ довольно сложно. Хочу продемонстрировать силу boost::mpl и показать трюк, позволяющий описывать шаблоны, полностью отказавшись от шаблонных шаблонных параметров.
Продемонстрирую проблему. Есть класс, принимающий тип объекта и тип контейнера для этого объекта.
template <typename T, typename Container>
struct A
{
typedef Container<T> type;
};
Так писать нельзя, вы должны использовать шаблонные шаблонные параметры, чтобы указать, что Container
сам по себе является шаблоном.
Правильно написать так:
template <typename T, template<typename> class Container>
struct A
{
typedef Container<T> type;
};
Использовать так:
typedef A<int, std::vector>::type type;
При первом же использовании мы получим ошибку компиляции. Мы забыли, что std::vector принимает два параметра, один из которых обычно используется по умолчанию. Хорошо, перепишем:
template <typename T, template<typename, typename> class Container>
struct A
{
typedef Container<T, std::allocator<T> > type;
};
Тут две явные проблемы:
Хотелось бы избежать явного указания типов по умолчанию и сложного синтаксиса шаблонных шаблонных параметров. На помощь приходит приём, основанный на использовании плейсхолдеров из boost::mpl, которые используются для создания лямбда метафункций.
Внешне разница лишь в том, что нужно передавать в наш шаблон не сам шаблон контейнера, а инстанцированный плейсхолдером шаблон контейнера, то есть вместо
typedef A<int, std::vector>::type type;
пишем
typedef A<int, std::vector<boost::mpl::_1> >::type type;
Чтобы инстанцировать инстанцированный плейсхолдером контейнер нужным типом используем boost::mpl::apply:
#include <boost/mpl/apply.hpp>
template <typename T, typename Container>
struct A
{
typedef typename boost::mpl::apply<Container, T>::type type;
};
Использование этого трюка в реальном программировании поможет упростить некоторые ваши запутанные шаблоны.
Автор: skor
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-3/41973
Ссылки в тексте:
[1] Источник: http://habrahabr.ru/post/191588/
Нажмите здесь для печати.