Наследование с помощью вариадических шаблонов - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь использовать наследование с переменными шаблонами.Во-первых, рассмотрим следующий фрагмент как скелет, на котором я хотел бы построить.

#include <type_traits>
#include <iostream>

template <typename K> class A1;   // fwd decl

template <typename K,
        template <typename> class NN = A1,
        class = typename std::enable_if< std::is_base_of< A1<K>, NN<K> >::value >::type >
class BB;

template <typename K>
class A1 { public: friend class BB<K>; };

template <typename K>
class A2 : public A1<K> {
};

template <typename K, template <typename> class NN>
class BB<K,NN> {
    NN<K>* ref;
public:
    BB() : ref{ new NN<K>{} } { std::cout << "ctor...\n"; };
};

int main() {
    BB<size_t> b1{};    //use default A1
    BB<size_t, A2> b2{};
}

Здесь мы имеем возможность использовать класс BB с любым классом, унаследованным от A1, который имеетровно 1 параметр шаблона.

Вопрос: Я бы хотел изменить этот шаблон таким образом, чтобы параметром шаблона NN мог быть любой класс, унаследованный от A1<K>, который также можетиметь произвольное количество дополнительных параметров шаблона, как я могу это сделать?Следующий фрагмент - грубая идея

template <typename K> class A1;   // fwd decl

template <typename K,
        template <typename, typename...> class NN = A1,
        class = typename std::enable_if< std::is_base_of< A1<K>, NN<K,typename...> >::value >::type,
        typename...Types >
class BB;

template <typename K>
class A1 { public: friend class BB<K>; };

template <typename K, typename V>
class A2 : public A1<K> {
    V local;
};

template <typename K,
        template <typename, typename...> class NN,
        typename...Types>
class BB<K,NN,void,Types...> {
    NN<K,Types...>* ref;
public:
    BB() : ref{ new NN<K,Types...>{} } { std::cout << "ctor...\n"; };
};

int main() {
    BB<size_t> b1{};    //use default A1
    BB<size_t, A2, char> b2{};  // can I specialize this way??
}

Возможно ли это сделать?Любая помощь очень ценится.VS2017 или GCC безразличны.

1 Ответ

0 голосов
/ 22 мая 2018
template <typename K> class A1;   // fwd decl

template<class...>struct types_t {};
template <class K0, class Types=types_t<>, template<class...>class NN=A1, class=void>
class BB;

template <typename K>
class A1 { public: friend class BB<K>; };

template <class K, class other>
class A2 : public A1<K> {
};

template<class K, class...Ks>
class A3 : public A1<K> {};

template<class K0, class...Ks, template<class...>class NN>
class BB<
    K0,
    types_t<Ks...>,
    NN,
    std::enable_if_t<
        std::is_base_of<
            A1<K0>,
            NN<K0, Ks...>
        >{}
    >
>{
    NN<K0, Ks...>* ref = nullptr;
public:
    BB() : ref{ new NN<K0, Ks...>{} } { std::cout << "ctor...\n"; };
};

int main() {
    BB<size_t> b1{};    //use default A1
    BB<size_t, types_t<char>, A2> b2{};
    BB<size_t, types_t<int, char>, A3> b3{};
}

это компилируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...