Nói tóm lại:tặng một kiểu enum chung như mẫu đối số
Có cách nào tôi có thể nuôi một lớp templated General
với một cái gì đó mà chỉ đại diện cho một loại enum
? Một cái gì đó như:
template <typename T> struct General {};
struct EnumSpecific : General<any_enum_type> {};
<int>
quá nhiều/không hoạt động trong trường hợp của tôi.
trường hợp cụ thể của tôi:
- Một templated
Holder
lớp xử lý bất kỳ loại dữ liệu trong một cách chung chung. - Lớp trừu tượng
General
triển khai các thuật toán cụ thể dựa trên hành vi củaHolder
. - Mẫu số kỹ thuật của
General
(nhưIntSpecific
,DoubleSpecific
,StringSpecific
,MoreSophisticatedTypeSpecific
..) xác định làm thế nào để đối phó với một sốHolder
loại bê tông. - Làm cách nào để xác định đúng thông số
EnumSpecific
?
Dưới đây là boilt xuống mã làm cho vấn đề của tôi xảy ra:
// 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;
}
tôi nên ăn gì các mẫu tranh cãi với trong EnumSpecific : General<??>
để làm cho mọi việc rõ ràng cho trình biên dịch?
Tôi có cần sử dụng một số loại khái niệm enum_type
và các công cụ phức tạp hơn từ lập trình chung không?
C++ 11 mang đến cho bạn 'std :: is_enum': http://en.cppreference.com/w/cpp/types/is_enum –
@AlanStokes Làm thế nào ngọt ngào của anh ta! Nhưng điều này không thể tự cung cấp thông số mẫu, phải không? Làm thế nào điều này có thể giúp tôi thực hiện các diễn viên? –
Có thể sử dụng lợi nhuận với 'enable_if'. Và 'inner_type' có thể giúp dàn diễn viên của bạn, mặc dù tôi thú nhận rằng tôi đã bị mất một chút trong mã của bạn ở giai đoạn đó. –