在我正在研究的C++项目中,我有一个标志值,它可以有四个值.这四个标志可以组合在一起.标志描述数据库中的记录,可以是:
现在,对于我希望保留此属性的每条记录,我可以使用枚举:
enum { xNew, xDeleted, xModified, xExisting }
Run Code Online (Sandbox Code Playgroud)
但是,在代码的其他地方,我需要选择哪些记录对用户可见,所以我希望能够将其作为单个参数传递,如:
showRecords(xNew | xDeleted);
Run Code Online (Sandbox Code Playgroud)
所以,似乎我有三个可能的附件:
#define X_NEW 0x01
#define X_DELETED 0x02
#define X_MODIFIED 0x04
#define X_EXISTING 0x08
Run Code Online (Sandbox Code Playgroud)
要么
typedef enum { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } RecordType;
Run Code Online (Sandbox Code Playgroud)
要么
namespace RecordType {
static const uint8 xNew = 1;
static const uint8 xDeleted = 2;
static const uint8 xModified = 4;
static const uint8 xExisting = 8;
}
Run Code Online (Sandbox Code Playgroud)
空间要求很重要(字节与整数),但并不重要.使用定义我失去了类型安全性,并且enum我失去了一些空间(整数),并且当我想要进行按位操作时可能需要进行转换.随着 …
假设我们有一些命名的枚举:
enum MyEnum {
FOO,
BAR = 0x50
};
Run Code Online (Sandbox Code Playgroud)
我搜索的是一个脚本(任何语言),它扫描我项目中的所有标题,并生成一个标题,每个枚举一个函数.
char* enum_to_string(MyEnum t);
Run Code Online (Sandbox Code Playgroud)
以及类似这样的实现:
char* enum_to_string(MyEnum t){
switch(t){
case FOO:
return "FOO";
case BAR:
return "BAR";
default:
return "INVALID ENUM";
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题确实与typedefed枚举和未命名的C风格枚举有关.有人知道这个吗?
编辑:解决方案不应该修改我的源,除了生成的函数.枚举是在API中,因此使用迄今为止提出的解决方案不是一种选择.
当我有类似的东西时,我想到了这个问题
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]如果我没有弄错的话就会允许这样的事情.)
我有一个经常出现的代码块,我循环遍历所有成员enum class.
for与新的相比,我目前使用的循环看起来非常笨拙range-based for.
有没有办法利用新的C++ 11功能来减少当前for循环的详细程度?
我希望改进的当前代码:
enum class COLOR
{
Blue,
Red,
Green,
Purple,
First=Blue,
Last=Purple
};
inline COLOR operator++( COLOR& x ) { return x = (COLOR)(((int)(x) + 1)); }
int main(int argc, char** argv)
{
// any way to improve the next line with range-based for?
for( COLOR c=COLOR::First; c!=COLOR::Last; ++c )
{
// do work
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,如果我可以做以下事情会很好:
for( const auto& c : COLOR )
{
// …Run Code Online (Sandbox Code Playgroud) 在http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx上有一个表格,显示了C++ 0x的功能这是在2010年RC实施的.其中列出了转发枚举和强类型枚举,但它们被列为"部分".该文章的主要内容表明,这意味着它们要么不完整,要么以某种非标准的方式实施.
所以我有VS2010RC并正在玩C++ 0x功能.我无法解决这些问题,也无法找到有关这两个功能的任何文档.甚至最简单的尝试都没有编译.
enum class E { test };
int main() {}
fails with:
1>e:\dev_workspace\experimental\2010_feature_assessment\2010_feature_assessment\main.cpp(518): error C2332: 'enum' : missing tag name
1>e:\dev_workspace\experimental\2010_feature_assessment\2010_feature_assessment\main.cpp(518): error C2236: unexpected 'class' 'E'. Did you forget a ';'?
1>e:\dev_workspace\experimental\2010_feature_assessment\2010_feature_assessment\main.cpp(518): error C3381: 'E' : assembly access specifiers are only available in code compiled with a /clr option
1>e:\dev_workspace\experimental\2010_feature_assessment\2010_feature_assessment\main.cpp(518): error C2143: syntax error : missing ';' before '}'
1>e:\dev_workspace\experimental\2010_feature_assessment\2010_feature_assessment\main.cpp(518): error C4430: missing type specifier - int assumed. Note: C++ … enumC++中的类型是相当基本的; 它基本上只是为标签创建了一堆编译时值(可能具有适当的范围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 …
为了使我的代码更短更容易更改,我想替换类似的东西
enum{ E_AAA, E_BBB, E_CCC };
static const char *strings{"AAA", "BBB", "CCC" };
Run Code Online (Sandbox Code Playgroud)
使用宏,如INIT(AAA,BBB,CCC); 但是当我尝试使用变量参数和字符串化做一个宏时,我得到一个错误,因为没有声明参数.
有关如何做到这一点的任何想法?
目前我正在使用枚举代表一个小游戏实验中的状态.我声明他们是这样的:
namespace State {
enum Value {
MoveUp = 1 << 0, // 00001 == 1
MoveDown = 1 << 1, // 00010 == 2
MoveLeft = 1 << 2, // 00100 == 4
MoveRight = 1 << 3, // 01000 == 8
Still = 1 << 4, // 10000 == 16
Jump = 1 << 5
};
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以这样使用它们:
State::Value state = State::Value(0);
state = State::Value(state | State::MoveUp);
if (mState & State::MoveUp)
movement.y -= mPlayerSpeed;
Run Code Online (Sandbox Code Playgroud)
但我想知道这是否是实现位标志的正确方法.是否有特殊的容器标志容器?我听说过std::bitset,这是我应该用的吗?你知道更高效的东西吗?
我做得对吗? …
想象一下,我们有一些具有数百种消息类型的协议,每种消息类型我们都希望通过C++类进行建模.由于每个类应该能够自动处理每个字段,因此一个自然的解决方案就是std::tuple拥有所有必需的类型:
std::tuple<int, double, char> message;
print(message); // the usual variadic magic
Run Code Online (Sandbox Code Playgroud)
这一切都很好.但是,现在我想给每个字段命名,我希望能够在引用代码中的字段时使用该名称,并获得它的文本表示.天真地,或者在C中,我可能写过:
struct Message
{
int header;
double temperature;
char flag;
};
Run Code Online (Sandbox Code Playgroud)
这样我们就失去了元组的递归自动处理能力,但我们可以从字面上命名每个字段.在C++中,我们可以通过枚举来做到这两点:
struct Message
{
enum FieldID { header, temperature, flag };
static const char * FieldNames[] = { "header", "temperature", "flag" };
typedef std::tuple<int, double, char> tuple_type;
template <FieldID I>
typename std::tuple_element<I, tuple_type>::type & get()
{ return std::get<I>(data); }
template <FieldID I>
static const char * name() { return FieldNames[I]; }
tuple_type data;
};
Run Code Online (Sandbox Code Playgroud)
现在我可以说Message …
我正在尝试为C++中的枚举创建一个简单的双向查找工具.我的单向查找工作正常......
enum MyEnum
{
One,
Two,
Three
};
const boost::unordered_map<MyEnum,std::string> MyEnumMap = map_list_of
(One, "One")
(Two, "Two")
(Three, "Three");
Run Code Online (Sandbox Code Playgroud)
然后看看
MyEnumMap.at(One)
Run Code Online (Sandbox Code Playgroud)
这有效,但它只允许基于密钥的查找.我想使用一个双向查找容器,如boost:bimap,以便根据值和键进行简单的反向查找.尽管如此,map_list_of似乎与boost :: bimap不兼容.
首先,我是否还应该使用带有boost :: bimap的map_list_of,还是需要另一种类型?
这些地图都是基本的(枚举,字符串)类型.
第二,有没有一种方法我仍然可以像上面那样以简单的方式将地图定义为const?我试图让这个更容易更新和维护,而不会进入太多额外的typedef等.非常感谢您的见解.
在C++中看到许多元编程的例子,它们可以找出类的属性(例如知道类型是否是模板的特化),或者知道类是否包含给定的嵌套类型; 但我想知道是否有可能编写一个测试或特征来确定最后一个的倒数 - 检查一个给定Type是否嵌套在一个class或struct.
换句话说,我正在寻找以下伪代码的等价物:
template <typename Type> struct is_nested {
enum { value = {__some magic__} };
};
typedef int type1;
struct Something { typedef int internal_type; };
typedef Something::internal_type type2;
//...later, likely at a different scope
is_nested< int >::value; // yields false
is_nested< std::vector<int>::iterator >::value; // yields true
is_nested< type1 >::value; // yields false
is_nested< type2 >::value; // yields true
Run Code Online (Sandbox Code Playgroud)
我知道我可以sizeof用来实现是/否测试,我认为Type是那些测试的一部分,但我无法弄清楚如何在测试中插入某种"任何可行的类型",这样我就可以形成一个表达式喜欢Anytype::Type.
template struct is_nested …
我一直在使用一个主要由不再在公司工作的程序员编写的大型代码库.其中一位程序员显然在他心中有一个特殊的位置,用于非常长的宏.我可以看到使用宏的唯一好处是能够编写不需要在所有参数中传递的函数(建议在我阅读的最佳实践指南中使用).除此之外,我认为内联函数没有任何好处.
有些宏是如此复杂,我很难想象有人甚至写它们.我尝试用这种精神创造一个,这是一场噩梦.调试是非常困难的,因为它在调试器中将N +行代码变为1(例如,在这个大块代码中的某处存在段错误.祝你好运!).我必须实际拉出宏并运行它非宏观调试它.我能看到这个人编写这些内容的唯一方法是在调试之后通过函数自动生成它们(或者比我聪明并且第一次完美地编写它,这总是可能的) .
我错过了什么吗?我疯了吗?有没有我不知道的调试技巧?请填写我.我真的很想听听观众中的宏观爱好者.:)
我有以下枚举和映射:
typedef enum {
MaxX = 0,
MaxY,
MaxCells,
MaxCycles,
Threes
} SettingName;
typedef std::map<SettingName, const char*> SettingNameCollection;
SettingNameCollection settingNames;
Run Code Online (Sandbox Code Playgroud)
我有以下函数来返回枚举名称:
const char* gofBoard::getSettingName(unsigned x) {
return settingNames[static_cast<SettingName>(x)];
}
Run Code Online (Sandbox Code Playgroud)
从我读到的内容来看,这应该可以工作,但该函数不会返回任何内容。没有编译时错误,也没有运行时错误。