为每个枚举器添加代码
Adding code for each enumerator
我有一些任意枚举,如下所示。
enum MyEnumWith2Items {
Item1,
Item2
};
enum MyEnumWith3Items {
Item1,
Item2,
Item3
};
我想添加一些依赖于每个枚举器的代码。例如,在与每个项目对应的类中添加一个字段。
template<typename EnumType>
struct MyStruct {
/* magic */
};
MyStruct<MyEnumWith2Items> a; // a has the fields i1 and i2, but not i3
MyStruct<MyEnumWith3Items> b; // b has i1, i2 and i3
这可能吗?enum class
怎么样?
使用static
字段或方法或任何类型的代码怎么样?
类定义可以采用任何形式,我的例子只是一个例子。
我可以使用任何版本的C++。
如果您对 myStruct
的静态成员感兴趣,请使用 C++14(因此静态模板成员可用(,您可以定义myStruct
如下
template <typename E>
struct myStruct
{
template <E I>
struct wrp
{ int value; };
template <E I>
static wrp<I> item;
};
template <typename E>
template <E I>
myStruct<E>::wrp<I> myStruct<E>::item { 0 };
并给出以下枚举器
enum MyEnumWith2Items { Item1, Item2 };
enum MyEnumWith3Items { Item3, Item4, Item5 };
你可以写
int main ()
{
myStruct<MyEnumWith2Items>::item<Item1>.value = 1;
myStruct<MyEnumWith2Items>::item<Item2>.value = 2;
myStruct<MyEnumWith3Items>::item<Item3>.value = 3;
myStruct<MyEnumWith3Items>::item<Item4>.value = 4;
myStruct<MyEnumWith3Items>::item<Item5>.value = 5;
}
在 C++14 之前(在 C++14 本身中(,您可以使用模板方法中的静态变量获得类似的结果;下面是一个完整示例
#include <iostream>
enum MyEnumWith2Items { Item1, Item2 };
enum MyEnumWith3Items { Item3, Item4, Item5 };
template <typename E>
struct myStruct
{
template <E I>
int & item ()
{ static int value = 0; return value; }
};
int main ()
{
myStruct<MyEnumWith2Items> e2;
myStruct<MyEnumWith3Items> e3;
e2.item<Item1>() = 1;
e2.item<Item2>() = 2;
e3.item<Item3>() = 3;
e3.item<Item4>() = 4;
e3.item<Item5>() = 5;
std::cout << "e2: " << e2.item<Item1>() << ", " << e2.item<Item2>()
<< std::endl; // print e2: 1, 2
std::cout << "e3: " << e3.item<Item3>() << ", " << e3.item<Item4>()
<< ", " << e3.item<Item5>() << std::endl; // print e3: 3, 4, 5
}
我的第一个想法是做这种事情,但有一个警告。
enum class Enum1 {a, b, size};
enum class Enum2 {c, d, e, size};
template<typename E>
struct S
{
char field[size_t(E::size)];
};
int main()
{
S<Enum1> s1;
S<Enum2> s2;
std::cout << sizeof(s1.field) << std::endl << sizeof(s2.field) << endl;
// 2 and 3
}
当然需要注意的是,enum
s 必须为 [0, n( 才能使最终的size
技巧起作用
这可能看起来有点多余,但如果需要,它确实允许多态类型。我已将不同的枚举类型包装到一组从基类型类继承的类中。然后我使用了具有专用化的模板结构。我还添加了通过模板参数列表或公开分配类设置值的功能。现在,这只是为了处理实际的枚举值;但是,您可以轻松地添加此内容以添加每种类型的字段。
#include <iostream>
class Root {
public:
enum Type {
TYPE_1 = 1,
TYPE_2,
TYPE_3
};
protected:
Type type_;
public:
explicit Root(Type type) : type_(type) {}
virtual ~Root() {}
Type getType() const {
return type_;
}
};
class Derived1 : public Root {
public:
enum TwoItems {
ITEM_1 = 1,
ITEM_2
} item_;
Derived1() : Root(TYPE_1) {}
explicit Derived1(unsigned itemValue) :
Root(TYPE_1), item_(static_cast<Derived1::TwoItems>(itemValue) ) {}
};
class Derived2 : public Root {
public:
enum ThreeItems {
ITEM_3 = 3,
ITEM_4,
ITEM_5
} item_;
Derived2() : Root(TYPE_2) {}
explicit Derived2(unsigned itemValue) :
Root(TYPE_2), item_(static_cast<Derived2::ThreeItems>(itemValue)) {}
};
class Derived3 : public Root {
public:
enum FourItems {
ITEM_6 = 6,
ITEM_7,
ITEM_8,
ITEM_9
} item_;
Derived3() : Root(TYPE_3) {}
explicit Derived3(unsigned itemValue) :
Root(TYPE_3), item_(static_cast<Derived3::FourItems>(itemValue)) {}
};
template<typename ClassType, unsigned itemValue = 0>
struct MyStruct {
ClassType derived_;
};
template<unsigned itemValue>
struct MyStruct<Derived1, itemValue> {
Derived1 derived_{ itemValue };
};
template<unsigned itemValue>
struct MyStruct<Derived2, itemValue> {
Derived2 derived_{ itemValue };
};
template<unsigned itemValue>
struct MyStruct<Derived3, itemValue> {
Derived3 derived_{ itemValue };
};
int main() {
MyStruct<Derived1, 2> structA;
MyStruct<Derived2, 4> structB;
MyStruct<Derived3, 8> structC;
std::cout << structA.derived_.item_ << std::endl;
std::cout << structB.derived_.item_ << std::endl;
std::cout << structC.derived_.item_ << std::endl;
std::cout << std::endl;
structA.derived_.item_ = static_cast<Derived1::TwoItems>(1);
structB.derived_.item_ = static_cast<Derived2::ThreeItems>(5);
structC.derived_.item_ = static_cast<Derived3::FourItems>(9);
std::cout << structA.derived_.item_ << std::endl;
std::cout << structB.derived_.item_ << std::endl;
std::cout << structC.derived_.item_ << std::endl;
std::cout << std::endl;
// Also
MyStruct<Derived1> structA2;
MyStruct<Derived2> structB2;
MyStruct<Derived3> structC2;
structA2.derived_.item_ = static_cast<Derived1::TwoItems>(1);
structB2.derived_.item_ = static_cast<Derived2::ThreeItems>(3);
structC2.derived_.item_ = static_cast<Derived3::FourItems>(7);
std::cout << structA2.derived_.item_ << std::endl;
std::cout << structB2.derived_.item_ << std::endl;
std::cout << structC2.derived_.item_ << std::endl;
char c;
std::cout << "nPress any key to quit.n";
std::cin >> c;
return 0;
}
相关文章:
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 尝试将另一个子句添加到代码中时出错
- Printf 命令不打印时添加了查找常见除数的新代码
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- 堆栈粉碎 在我在代码中添加新变量以及一些操作后C++检测到
- 添加新行时工作代码引发异常.调试技巧?
- 如何将默认代码添加到我在 vim 中打开的每个 cpp 文件?
- 在大括号内添加语句会更改代码功能?
- 使用哪种模式来执行新代码,只需添加基类的新子类?
- 我应该在服务模板中的什么位置添加自己的代码?
- 为每个枚举器添加代码
- 为什么添加代码会破坏工作,即使它没有执行?
- 如何在C 中添加代码延迟
- 向 QT C++添加代码示例
- 带有严重错误处理的简单添加代码
- 如何在运行时中添加代码
- 在Model上添加操作而不向Model中添加代码
- 向Jetbrains Clion添加c++代码片段
- 如何使用c++模板根据函数参数值添加代码片段