2013-05-22 2 views
1

Я пытаюсь создать утилиту, которая включает в себя наследование из одной базы несколько раз, что я делаю, создавая шаблоны для целого числа, чтобы сделать базы отличными. К сожалению, я нашел себя писать что-то вроде следующего:Шаблоны с переменным количеством помеченных оснований

template<size_t I> 
struct X {}; 

template<size_t Len> 
struct Y { static_assert(false, "exceeded max length"); }; 

template<> 
struct Y<0> {}; 

template<> 
struct Y<1> : X<0> {}; 

template<> 
struct Y<2> : X<0>, X<1> {}; 

template<> 
struct Y<3> : X<0>, X<1>, X<2> {}; 

Хотя это имело обыкновение быть очень распространенным узором в старые времена противной C++, я не могу помочь, но чувствую себя лучше, может быть сделано в C + +11, хотя детали ускользают от меня.

Это можно сделать succintly, для любых Len?

(любые идеи для лучшего заголовка также оценили)

+0

Из любопытства, зачем вам это нужно? – hmjd

+0

@hmjd Это довольно запутанно, но требует многократного повторения одного и того же виртуального обратного вызова и одновременного регистрации только одного. Надеюсь, создав универсальную утилиту, которая делает это выше (с реализацией в классах), я могу избавиться от большого фрагмента кода. – jleahy

ответ

3

Если иерархия не должна быть плоской, то:

#include <iostream> 
#include <iomanip> 
#include <type_traits> 

template<size_t N> struct X : X<N - 1> {}; 
template<> struct X<0> {}; 

template<size_t N> 
struct Y : X<N - 1> {}; 

int main() 
{ 
    std::cout << std::boolalpha; 
    std::cout << std::is_base_of<X<0>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<1>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<2>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<3>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<4>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<5>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<6>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<7>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<8>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<9>, Y<10>>::value << "\n"; // true 
    std::cout << std::is_base_of<X<10>, Y<10>>::value << "\n"; // false 

} 

Смотреть онлайн демо на http://ideone.com/wsgAhQ.

+0

Небольшой недостаток заключается в том, что 'X' связаны: чтобы исправить это, 'Y's наследует линейно, причем каждый наследует от' X' и 'Y <-1>' bejng empty. 'Y' может даже взять' template класс X' в качестве аргумента вместо того, чтобы быть жестко запрограммированным. – Yakk

1

Что случилось с немного рекурсивного наследования?

template<size_t I> 
struct X {}; 

template<size_t I> 
struct InheritFromX : X<I> , InheritFromX <I-1> {}; 

template<> 
struct InheritFromX<0> {}; 

struct Mystruct : InheritFromX<3> { } // inherits X 3 times 
Смежные вопросы