不确定是否可以使用模板完成,但我想尝试一下。
我有一个模板类,它接受任何结构,存储它并返回它。 另外,我想要一个接口,可以在需要时重置struct的数据。
#define MYDEFAULT {1,2,3} template < typename ITEM, ITEM Default> class myClass{ public: myClass(ITEM item) : _item(item) {} const ITEM* get(){ return &_item; } void reset(){ _item = Default; } ITEM _item; }; // Set to default when instantiated myClass<myStruct, MYDEFAULT> ABC(MYDEFAULT);当然这根本不起作用,但我想要实现的是在reset()替换Default 。 我的意思是,如果_item是int类型,它会起作用。 怎么能实现呢?
编辑:我想要这样的事情:
template <typename Y, Y T> class myclass { public: void reset() { xxx = T; } Y xxx{10}; }; void test() { myclass<int, 5> _myclass; }最初xxx是10并且在调用reset之后它是5.这是有效的,所以它似乎不可能用于POD或类类型?
EDIT2:似乎所有关于非类型模板参数。 https://stackoverflow.com/a/2183121/221226因此在使用结构时无法绕过特征。
Not sure if this can be done using templates but I want to give it a try.
I have a template class which takes any struct, stores it and returns it. Additionally, I want an interface that resets the struct's data whenever requested.
#define MYDEFAULT {1,2,3} template < typename ITEM, ITEM Default> class myClass{ public: myClass(ITEM item) : _item(item) {} const ITEM* get(){ return &_item; } void reset(){ _item = Default; } ITEM _item; }; // Set to default when instantiated myClass<myStruct, MYDEFAULT> ABC(MYDEFAULT);Of course that's not working at all, but what I want to achieve is the replacement of Default in reset(). I mean it would work if _item would be of type int. How can this be realized?
EDIT: I want something like this:
template <typename Y, Y T> class myclass { public: void reset() { xxx = T; } Y xxx{10}; }; void test() { myclass<int, 5> _myclass; }Initially xxx is 10 and after invoking reset it is 5. This works, so it seems it is not possible for POD or class types?
EDIT2: It seems it is all about non-type template-arguments. https://stackoverflow.com/a/2183121/221226 So there is no way around traits when using structs.
最满意答案
作为可行的解决方案,您可以使用特征类,如以下工作示例所示:
#include<cassert> struct S { int i; }; template<typename T> struct Traits { static constexpr auto def() { return T{}; } }; template<> struct Traits<S> { static constexpr auto def() { return S{42}; } }; template <typename ITEM> class myClass { public: myClass(): _item(Traits<ITEM>::def()) {} myClass(ITEM item): _item(item) {} const ITEM* get() { return &_item; } void reset() { _item = Traits<ITEM>::def(); } ITEM _item; }; int main() { myClass<S> ABC{}; myClass<int> is; assert((ABC.get()->i == 42)); assert((*is.get() == 0)); }基本特征使用ITEM类型的默认构造函数。 然后,只要您想要特定类的不同默认值,就可以对其进行专门化。
即使使用工厂功能,也可以实现同样的目的:
template<typename T> constexpr auto def() { return T{}; } template<> constexpr auto def<S>() { return S{42}; }无论如何,特征可以很容易地同时提供更多类型和功能。
As a viable solution, you can use a trait class as shown in the following working example:
#include<cassert> struct S { int i; }; template<typename T> struct Traits { static constexpr auto def() { return T{}; } }; template<> struct Traits<S> { static constexpr auto def() { return S{42}; } }; template <typename ITEM> class myClass { public: myClass(): _item(Traits<ITEM>::def()) {} myClass(ITEM item): _item(item) {} const ITEM* get() { return &_item; } void reset() { _item = Traits<ITEM>::def(); } ITEM _item; }; int main() { myClass<S> ABC{}; myClass<int> is; assert((ABC.get()->i == 42)); assert((*is.get() == 0)); }The basic trait uses the default constructor of the type ITEM. You can then specialize it whenever you want a different defaulted value for a specific class.
The same can be accomplished even with a factory function as:
template<typename T> constexpr auto def() { return T{}; } template<> constexpr auto def<S>() { return S{42}; }Anyway, traits can easily provide more types and functions all at once.
更多推荐
发布评论