相关疑难解决方法(0)

我应该使用#define,enum还是const?

在我正在研究的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我失去了一些空间(整数),并且当我想要进行按位操作时可能需要进行转换.随着 …

c++ enums bit-manipulation c-preprocessor

123
推荐指数
6
解决办法
6万
查看次数

有没有一种简单的方法将C++枚举转换为字符串?

假设我们有一些命名的枚举:

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中,因此使用迄今为止提出的解决方案不是一种选择.

c++ string scripting enums

118
推荐指数
12
解决办法
11万
查看次数

(怎么样)我可以计算枚举中的项目吗?

当我有类似的东西时,我想到了这个问题

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]如果我没有弄错的话就会允许这样的事情.)

c++ enumeration count

91
推荐指数
3
解决办法
10万
查看次数

允许使用枚举类的基于范围的For?

我有一个经常出现的代码块,我循环遍历所有成员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)

c++ enums for-loop c++11

65
推荐指数
5
解决办法
4万
查看次数

VS2010中的前向/强大枚举

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++ …

c++ visual-studio-2010 c++11

27
推荐指数
2
解决办法
9451
查看次数

可搜索的类似Enum的对象,包含字符串和int转换

介绍

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)等,有很多问题.而且普遍的共识是,没有确定 -火的方式做到这一点.

第N个元素技巧

仅当您强制执行枚举值为正且增加时,以下模式才有效:

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 …

c++ c++11

25
推荐指数
1
解决办法
1494
查看次数

从C++宏创建字符串列表和枚举列表

为了使我的代码更短更容易更改,我想替换类似的东西

enum{ E_AAA, E_BBB, E_CCC };
static const char *strings{"AAA", "BBB", "CCC" };
Run Code Online (Sandbox Code Playgroud)

使用宏,如INIT(AAA,BBB,CCC); 但是当我尝试使用变量参数和字符串化做一个宏时,我得到一个错误,因为没有声明参数.

有关如何做到这一点的任何想法?

c c++ macros variadic c-preprocessor

19
推荐指数
5
解决办法
2万
查看次数

enum是实现位标志的规范方法吗?

目前我正在使用枚举代表一个小游戏实验中的状态.我声明他们是这样的:

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++ enums bit-manipulation bitflags std-bitset

11
推荐指数
3
解决办法
7173
查看次数

如何设计带有"注释"字段的类?

想象一下,我们有一些具有数百种消息类型的协议,每种消息类型我们都希望通过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++ class-design field

9
推荐指数
1
解决办法
1048
查看次数

枚举的boost :: bimap

我正在尝试为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++ boost map bimap

6
推荐指数
1
解决办法
1856
查看次数

C++ - 知道类型/类是否嵌套?

在C++中看到许多元编程的例子,它们可以找出类的属性(例如知道类型是否是模板的特化),或者知道类是否包含给定的嵌套类型; 但我想知道是否有可能编写一个测试或特征来确定最后一个的倒数 - 检查一个给定Type是否嵌套在一个classstruct.

换句话说,我正在寻找以下伪代码的等价物:

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 …

c++ templates nested traits

6
推荐指数
1
解决办法
463
查看次数

大C宏.有什么好处?

我一直在使用一个主要由不再在公司工作的程序员编写的大型代码库.其中一位程序员显然在他心中有一个特殊的位置,用于非常长的宏.我可以看到使用宏的唯一好处是能够编写不需要在所有参数中传递的函数(建议在我阅读的最佳实践指南中使用).除此之外,我认为内联函数没有任何好处.

有些宏是如此复杂,我很难想象有人甚至写它们.我尝试用这种精神创造一个,这是一场噩梦.调试是非常困难的,因为它在调试器中将N +行代码变为1(例如,在这个大块代码中的某处存在段错误.祝你好运!).我必须实际拉出宏并运行它非宏观调试它.我能看到这个人编写这些内容的唯一方法是在调试之后通过函数自动生成它们(或者比我聪明并且第一次完美地编写它,这总是可能的) .

我错过了什么吗?我疯了吗?有没有我不知道的调试技巧?请填写我.我真的很想听听观众中的宏观爱好者.:)

c macros

5
推荐指数
2
解决办法
2313
查看次数

将 C++ 枚举映射为 const char*

我有以下枚举和映射:

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)

从我读到的内容来看,这应该可以工作,但该函数不会返回任何内容。没有编译时错误,也没有运行时错误。

c++ dictionary

4
推荐指数
1
解决办法
5277
查看次数