Короче:Дайте общий тип перечисления в качестве аргумента шаблона
Есть ли способ, что я могу кормить General
шаблонный класс с чем-то, что только представляют enum
тип? Что-то вроде:
template <typename T> struct General {};
struct EnumSpecific : General<any_enum_type> {};
<int>
слишком много/не работает в моем случае.
Мой конкретный случай:
- шаблонного
Holder
класс обрабатывает любые данные в общем виде. - Класс абстрактных классов
General
реализует конкретные алгоритмы, основанные на поведенииHolder
s. - шаблона спецификации
General
(какIntSpecific
,DoubleSpecific
,StringSpecific
,MoreSophisticatedTypeSpecific
..) определить, как иметь дело с некоторыми конкретнымиHolder
типов. - Как я могу правильно определить спецификацию
EnumSpecific
?
Здесь boilt вниз код делает мою проблему произойти:
// A templated value holder:
template <typename T>
class Holder {
public:
Holder(T const& t) : _value(t) {};
// generic methods
void generics() {};
// methods concerning the value:
void set(T const& t /*, setInfo */) {
// .. check for an actual change, notify buddies of the change..
_value = t;
};
T value(/*readInfo*/) {
// .. do stuff depending on how/why the value is read..
return _value;
};
private:
T _value;
};
// (in reality, all `generics` methods come from a parent, untemplated class)
// A generic process involving such `Holder`s:
template <typename T>
class General {
public:
typedef bool /* or anything */ KnownReturnTypes;
General(Holder<T>* const a
, Holder<T>* const b)
: _a(a)
, _b(b)
{};
void methods() {
// Use common behavior of all `Holder`'s
_a->generics();
// .. or methods that rely on the actual values:
KnownReturnTypes knr(valuedMethods());
if (knr) {} else {}
// ...
};
// Use polymorphism to adapt to each situation..
virtual KnownReturnTypes valuedMethods() = 0;
protected:
Holder<T>* _a;
Holder<T>* _b;
};
// Example of specialization for integral types (there might be others)
class IntSpecific : General<int> {
public:
IntSpecific(Holder<int>* const a
, Holder<int>* const b)
: General<int>(a, b)
{};
// implement the valuedMethods:
virtual KnownReturnTypes valuedMethods() {
return _a->value() > _b->value(); // dummy
}
};
// Specialization for enum types:
// * * * class EnumSpecific : General<any_enum_type> { // does not exist * *
class EnumSpecific : General<int> {
public:
EnumSpecific(Holder<int>* const a
, Holder<int>* const b)
: General<int>(a, b)
{};
// only use properties and methods offered by an enum type:
virtual KnownReturnTypes valuedMethods() {
return _a->value() == _b->value(); // dummy
}
};
// One particular case
typedef enum {One, Two, Three} Enum;
typedef Holder<Enum> EnumHolder;
int main() {
// Check that `IntSpecific` works fine.
Holder<int>* i(new Holder<int>(3));
Holder<int>* j(new Holder<int>(5));
IntSpecific is(i, j); // ok.
// Try the `EnumSpecific`
EnumHolder* a(new EnumHolder { One });
EnumHolder* b(new EnumHolder { Two });
EnumSpecific es(static_cast<Holder<int>*>(a) // invalid cast
, static_cast<Holder<Enum>*>(b)); // unexpected type
// This is because the compiler doesn't know enough about what
// EnumSpecific actually *is*. How to tell him more about it?
return EXIT_SUCCESS;
}
Что я должен кормить аргумент шаблона с в EnumSpecific : General<??>
, чтобы сделать вещи ясно для компилятора?
Нужно ли использовать какую-то концепцию enum_type
и более сложные инструменты от общего программирования?
C++ 11 дает 'зЬй :: is_enum': http://en.cppreference.com/w/cpp/types/is_enum –
@AlanStokes Как мило с его стороны! Но это не может самостоятельно подать параметр шаблона, не так ли? Как это может помочь мне выполнить бросок? –
Его можно было бы выгодно использовать с 'enable_if'. И 'basic_type' может помочь с вашим приведением, хотя, признаюсь, на этом этапе я немного потерял ваш код. –