当我有类似的东西时,我想到了这个问题
enum Folders {FA, FB, FC};
Run Code Online (Sandbox Code Playgroud)
并希望为每个文件夹创建一个容器数组:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
Run Code Online (Sandbox Code Playgroud)
(使用的地图是更优雅的使用方法:std::map<Folders, ContainerClass*> m_containers;
)
但回到我原来的问题:如果我不想对数组大小进行硬编码,有什么方法可以找出文件夹中有多少项?(不依赖于例如FC
列表中的最后一项,ContainerClass*m_containers[FC+1]
如果我没有弄错的话就会允许这样的事情.)
在你问之前,我已经在SO上寻找并寻找了这个,但是找不到可靠的答案.
我需要能够动态迭代具有非增量值的枚举,例如:
typedef enum {
CAPI_SUBTYPE_NULL = 0, /* Null subtype. */
CAPI_SUBTYPE_DIAG_DFD = 1, /* Data Flow diag. */
CAPI_SUBTYPE_DIAG_ERD = 2, /* Entity-Relationship diag. */
CAPI_SUBTYPE_DIAG_STD = 3, /* State Transition diag. */
CAPI_SUBTYPE_DIAG_STC = 4, /* Structure Chart diag. */
CAPI_SUBTYPE_DIAG_DSD = 5, /* Data Structure diag. */
CAPI_SUBTYPE_SPEC_PROCESS = 6, /* Process spec. */
CAPI_SUBTYPE_SPEC_MODULE = 7, /* Module spec. */
CAPI_SUBTYPE_SPEC_TERMINATOR = 8, /* Terminator spec. */
CAPI_SUBTYPE_DD_ALL = …
Run Code Online (Sandbox Code Playgroud) enum
C++中的类型是相当基本的; 它基本上只是为标签创建了一堆编译时值(可能具有适当的范围enum class
).
将相关的编译时常量分组在一起非常有吸引力:
enum class Animal{
DOG,
CAT,
COW,
...
};
// ...
Animal myAnimal = Animal::DOG;
Run Code Online (Sandbox Code Playgroud)
然而,它有各种各样的缺点,包括:
在这篇文章中,我试图创建一种解决这些缺点的类型.
一个理想的解决方案采用常量的编译时知识及其与字符串的关联的概念,并将它们组合成一个类似于scoped-enum的对象,可以通过enum id和enum string name进行搜索.最后,结果类型将使用尽可能接近枚举语法的语法.
在这篇文章中,我将首先概述其他人为各个部分所尝试的内容,然后介绍两种方法,一种完成上述方法,但由于静态成员的初始化顺序而具有未定义的行为,另一种解决方案不那么漂亮语法但由于初始化顺序没有未定义的行为.
关于获取枚举中的项目数量(1 2 3)以及网上提出的大量其他问题(4 5 6)等,有很多问题.而且普遍的共识是,没有确定 -火的方式做到这一点.
仅当您强制执行枚举值为正且增加时,以下模式才有效:
enum Foo{A=0, B, C, D, FOOCOUNT}; // FOOCOUNT is 4
Run Code Online (Sandbox Code Playgroud)
但是,如果您尝试编码某种需要任意值的业务逻辑,则很容易被破坏:
enum Foo{A=-1, B=120, C=42, D=6, FOOCOUNT}; // ????
Run Code Online (Sandbox Code Playgroud)
所以Boost的开发人员试图用Boost.Enum来解决这个问题,Boost.Enum使用了一些相当复杂的宏来扩展到一些至少会给你大小的代码.
在迭代枚举中有一些尝试; 可以迭代的类似枚举的对象,理论上允许隐式大小计算,甚至在[7](7 8 9,...)的情况下明确允许
尝试实现这一点通常会导致自由浮动函数和使用宏来适当地调用它们.(8 …
我有一个枚举类型StackID
,我使用枚举来引用特定向量的索引,它使我的代码更容易阅读.
但是,我现在需要创建一个名为nextAvail
type 的变量StackID
.(它实际上指的是特定的stackID).我尝试增加它,但在C++中,以下是非法的:
nextAvail++;
Run Code Online (Sandbox Code Playgroud)
哪种对我有意义...因为没有界限检查.
我可能忽略了一些明显的东西,但什么是一个很好的替代品呢?
我也想链接到这个问题.
我有一些C++代码,其中声明了以下枚举:
enum Some
{
Some_Alpha = 0,
Some_Beta,
Some_Gamma,
Some_Total
};
int array[Some_Total];
Run Code Online (Sandbox Code Playgroud)
Alpha,Beta和Gamma的值是顺序的,我很乐意使用以下循环来迭代它们:
for ( int someNo = (int)Some_Alpha; someNo < (int)Some_Total; ++someNo ) {}
Run Code Online (Sandbox Code Playgroud)
这个循环没问题,直到我决定改变枚举中声明的顺序,比如说,使Beta成为第一个值,而Alpha - 第二个.这使循环标头无效,因为现在我必须从Beta迭代到Total.那么,迭代枚举的最佳实践是什么?我希望迭代所有值,而不是每次都更改循环标题.我能想到一个解决方案:
enum Some
{
Some_Start = -1,
Some_Alpha,
...
Some_Total
};
int array[Some_Total];
Run Code Online (Sandbox Code Playgroud)
并从(Start + 1)迭代到Total,但它看起来很难看,我从未见过有人在代码中这样做.是否有任何众所周知的范例来迭代枚举,或者我只需要修复枚举值的顺序?(让我们假装,我真的有一些很棒的理由来改变枚举值的顺序)......
可能的重复:
枚举C++
C++中的枚举:迭代枚举
我有一个二十一点游戏的卡片类,有以下枚举:
enum Rank { Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King };
enum Suit { Clubs, Diamonds, Hearts, Spades };
Run Code Online (Sandbox Code Playgroud)
当我创建甲板时,我想编写如下代码:
// foreach Suit in Card::Suit
// foreach Rank in Card::Rank
// add new card(rank, suit) to deck
Run Code Online (Sandbox Code Playgroud)
我相信c ++中没有foreach.但是,我如何遍历枚举?
谢谢,斯宾塞
假设我们有一个枚举类型E
.
enum class E : underlying_type_of_E {
v1 = uE1,
v2 = uE2,
//...
vN = uEN
};
typedef typename std::underlying_type<E>::type uE;
Run Code Online (Sandbox Code Playgroud)
一般而言,并非所有值uE
都是有效值E
,因为我们可以选择它们之间的关系.是否有一种创建随机,有效(在定义中命名,不可分配),E的值的一般方法?例如,这不起作用:
std::mt19937 m;
std::uniform_int_distribution<uE> randomUE(0, std::numeric_limits<uE>::max());
E e = static_cast<E>( randomUE(m) );
Run Code Online (Sandbox Code Playgroud)
因为:
鉴于所有枚举值在编译时都是已知的,我无法想象为什么这会以任何方式危险或容易出错.
至于为什么我想要这样的事情 - 我正在研究一种使用模板化基因存储的遗传算法.现在,我使用枚举作为染色体并将它们存储在按需std::vector<bool>
转换中std::vector<enumT>
.这种方法的问题是以给定概率翻转随机位的突变.这可能会导致问题,因为它会产生无效的染色体,这些染色体是未命名的枚举值.
这个问题来自我之前的一个问题:为什么 C++ 运算符 new/delete/variants 不应该出现在头文件中?. 快速总结一下,我正在学习覆盖全局 operator new
、delete
等。我现在需要一个自定义分配器类(我的重载 operator new call std::set::insert(...)
,它本身似乎是 call new
,因此无限回避)。我认为,如果我向我提供自定义分配器(例如,使用malloc
而不是new
),我std::set
可以绕过无限递归。
我已经阅读了一些关于实现自定义分配器的文章,但对struct rebind
.
这里有一个很好的问答:解析分配器::重新绑定调用,但我仍然对一个特定项目感到困惑。cplusplus.com 说struct rebind
:
它的成员类型 other 是分配类型类型元素的等效分配器类型
我不明白怎么other
是其成员struct rebind
。struct rebind
我发现的定义如下:
template <class Type> struct rebind {
typedef allocator<Type> other;
};
Run Code Online (Sandbox Code Playgroud)
我看不出other
是一个成员变量struct rebind
。这只是typedef
ed。如果我typedef int foo;
在全局命名空间中做了,那并不意味着int
在全局命名空间中声明了一个类型为全局的变量,那么反过来,如何other
成为 的成员struct …
我想知道是否有可能编写一个类似std::tie()
函数(使用模板编程),它只能绑定元组的选择组件,并将其他元素绑定到某些占位符std::bind()
.如果是这样,只需要为他/她感兴趣的部分声明变量.
例如,
std::tie(x,_1,y,_2) = (2,3,4,5);
Run Code Online (Sandbox Code Playgroud)