Можно ли создать пакет параметров?

Рассмотрим следующий псевдокод:

template<class... T>
struct worker : unique<T...>::type...{};
struct x{};
struct y{};
struct z{};

Можно ли написать шаблон unique так что он генерирует пакет параметров, состоящий только из уникальных типов среди Tс, так что worker<x,y,x,z> будет напрямую получен из x, y, z соответственно в указанном порядке Ts не финальные классы?

2 ответа

Решение

AFAIK: Нет.

Проблема в том, что type является результатом typedef директива, и typedef не может псевдоним пакетов. Это на самом деле беспокоит, и чаще всего вычисления для пакетов требуют введения типа оболочки (например, template <typename...> struct pack {};) просто чтобы иметь возможность передать их.

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

Вот реализация этого подхода с использованием Boost.MPL:

#include <boost/mpl/fold.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>

namespace mpl = boost::mpl;

template < typename ...Args >
struct inherit_uniquely
{
    // filter out duplicates
    typedef typename
        mpl::fold<
            mpl::vector< Args... >,
            mpl::set0<>,
            mpl::insert< mpl::_1, mpl::_2 >
        >::type unique_bases;

    // create base type
    typedef typename
        mpl::inherit_linearly<
            unique_bases,
            mpl::inherit< mpl::_1, mpl::_2 >
        >::type type;
};

template < typename ...Bases >
struct Derived : inherit_uniquely< Bases... >::type
{};

struct X { int x;};
struct Y { int y;};
struct Z { int z;};

int main()
{
    Derived< X, Y, Z > d;
    d.x = 1;
    d.y = 2;
    d.z = 3;

    X& d_as_x = d;
    Y& d_as_y = d;
    Z& d_as_z = d;
}
Другие вопросы по тегам