相关疑难解决方法(0)

枚举类型的命名空间 - 最佳实践

通常,人们需要一起使用几种枚举类型.有时,一个人有一个名字冲突.我想到了两种解决方案:使用命名空间,或使用"更大"的枚举元素名称.仍然,命名空间解决方案有两种可能的实现:具有嵌套枚举的虚拟类或完整的命名空间.

我正在寻找这三种方法的优缺点.

例:

// oft seen hand-crafted name clash solution
enum eColors { cRed, cColorBlue, cGreen, cYellow, cColorsEnd };
enum eFeelings { cAngry, cFeelingBlue, cHappy, cFeelingsEnd };
void setPenColor( const eColors c ) {
    switch (c) {
        default: assert(false);
        break; case cRed: //...
        break; case cColorBlue: //...
        //...
    }
 }


// (ab)using a class as a namespace
class Colors { enum e { cRed, cBlue, cGreen, cYellow, cEnd }; };
class Feelings { enum e { cAngry, cBlue, cHappy, cEnd …
Run Code Online (Sandbox Code Playgroud)

c++ enums scope nested

98
推荐指数
7
解决办法
7万
查看次数

在交换机中捕获混合枚举

在一些遗留代码中,我有很多枚举,以及一​​个巨大的切换案例.我想测试一下开关是否具有纯枚举类型.无意义的例子:

typedef enum EN
{
    EN_0,
    EN_1
} EN_T;

typedef enum DK
{
    DK_0,
    DK_1
} DK_T;

EN_T bar = ...
switch( bar )
{
    case EN_0:
    ...
    break;
    case DK_1: //<-- mixed type
    ...
    break;
}
Run Code Online (Sandbox Code Playgroud)

我试着编译它gcc with -Wall -Wextra -pedantic,并没有得到任何警告.有关如何测试的任何想法?作为编译器警告或专用测试代码.由于交换机和枚举都有100多个成员,因此它必须是某种程度的通用.

编辑:请注意我不关心这是否合法c,根据C标准.

这是不好的做法,编译器可以警告不良做法或潜在的错误,不会违反标准,if( a = 1)...总是如此,完全合法,但可能是一个错误.

如果枚举上的开关不包含该枚举aso的所有值,我可以使编译器发出警告

如果编译器可以工作,那是首选,但如果像lint或类似的工具可以做到这一点,我也会很开心.

c enums

11
推荐指数
2
解决办法
1131
查看次数

C++ 17:仍然使用枚举作为常量?

我习惯使用enum常量 - 它们可以快速编写,可以放在.h文件中,并且工作正常.

enum {BOX_LEFT=10, BOX_TOP=50, BOX_WIDTH=100, BOX_HEIGHT=50};
enum {REASONS_I_LIKE_ENUM_AS_CONSTANTS = 3};
Run Code Online (Sandbox Code Playgroud)

这不再是个好主意吗?

我认为有更好的理由选择枚举类(传统的枚举隐式转换为int;常规枚举将其枚举器导出到周围的范围),但这些是在这种情况下更喜欢旧枚举的原因.

我在一个关于静态constexpr int和旧式枚举的线程中看到旧式枚举更好,因为有了一个静态的constexpr成员,你必须在类外面声明它.但是这在C++ 17中显然不再适用,并且可能只适用于类成员.

什么是c ++ 17的首选方式?

c++ enums c++17

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

如何在 C++ 中使用选项 true、false、default 和 toggle 实现标志?

我目前正在尝试提出一种巧妙的方法来实现标志,除了通常的“true”和“false”之外,还包括状态“default”和(可选)“toggle”。

标志的一般问题是,它有一个函数并希望通过传递某些参数来定义其行为(“做某事”或“不做某事”)。

单旗

使用单个(布尔值)标志,解决方案很简单:

void foo(...,bool flag){
    if(flag){/*do something*/}
}
Run Code Online (Sandbox Code Playgroud)

在这里添加默认值特别容易,只需将函数更改为

void foo(...,bool flag=true)
Run Code Online (Sandbox Code Playgroud)

并在没有标志参数的情况下调用它。

多个标志

一旦标志数量增加,我通常看到和使用的解决方案是这样的:

typedef int Flag;
static const Flag Flag1 = 1<<0;
static const Flag Flag2 = 1<<1;
static const Flag Flag3 = 1<<2;

void foo(/*other arguments ,*/ Flag f){
    if(f & Flag1){/*do whatever Flag1 indicates*/}
    /*check other flags*/
}

//call like this:
foo(/*args ,*/ Flag1 | Flag3)
Run Code Online (Sandbox Code Playgroud)

这样做的好处是,您不需要每个标志的参数,这意味着用户可以设置他喜欢的标志,而只需忘记他不关心的标志。特别是你不会接到电话,比如foo (/*args*/, true, false, true)你必须计算哪个真/假表示哪个标志。

这里的问题是:
如果你设置了一个默认参数,一旦用户指定了任何标志,它就会被覆盖。不可能像Flag1=true, Flag2=false, Flag3=default.

显然,如果我们想要 3 个选项(真、假、默认),我们需要为每个标志至少传递 2 位。因此,虽然它可能不是必需的,但我想任何实现都应该很容易使用第 …

c++ flags bitflags

5
推荐指数
1
解决办法
2644
查看次数

防止在C ++中将整数转换为枚举

假设我们有

enum class Month {jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};
Run Code Online (Sandbox Code Playgroud)

每个值都是一个0到11的整数。然后,我希望Month类型的变量仅保存这些枚举值。因此,这是创建变量的唯一可行方法:

Month m = Month::may;
Run Code Online (Sandbox Code Playgroud)

但是以下是该语言允许的其他一些方式:

Month m1 = Month(12345);
Month m2 = static_cast<Month>(12345);
Run Code Online (Sandbox Code Playgroud)

这有点令人失望。我如何只允许第一种方式?或者人们如何应对C ++中的穷举枚举?

c++ enums

5
推荐指数
1
解决办法
392
查看次数

SWIG 和 C++ 枚举类

编辑这个答案解决了问题,但最后我提出了一个更加模块化的解决方案。一探究竟 :)

我从两次 讨论中知道,为了类型安全,enum class应该选择哪个。enum出于这个原因,我在我的项目中使用它,但是当用 SWIG 包装它们时,我得到了一些我不太喜欢的东西。

给出简单的枚举

enum class type {
    A, B, C, D, E, F, G, H, I
};
Run Code Online (Sandbox Code Playgroud)

在一个.hpp文件中,比如说my_types.hpp,并且该my_types.i文件:

%module my_types
%{
#include "my_types.hpp"
%}
%include "my_types.hpp"
Run Code Online (Sandbox Code Playgroud)

生成的python文件包含包含

type_A = _my_types.type_A
type_B = _my_types.type_B
type_C = _my_types.type_C
type_D = _my_types.type_D
type_E = _my_types.type_E
type_F = _my_types.type_F
type_G = _my_types.type_G
type_H = _my_types.type_H
type_I = _my_types.type_I
Run Code Online (Sandbox Code Playgroud)

这意味着当在Python中使用它时我必须这样做

import my_types as mt
mt.type_A …
Run Code Online (Sandbox Code Playgroud)

c++ enums swig python-3.x

5
推荐指数
1
解决办法
2548
查看次数

为什么我被允许使用不完整的枚举类?

为什么下面的代码编译没有任何错误?

enum class Enumeration;
void func()
{
    auto enumeration = static_cast<Enumeration>(2);
    auto value = static_cast<int>(enumeration);
}
Run Code Online (Sandbox Code Playgroud)

c++

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

在 C++ 中将 int 值分配给 enum,反之亦然

#include <iostream>    

typedef enum my_time {
  day,
  night
} my_time;

int main(){    
  // my_time t1 = 1; <-- will not compile
  int  t2 = night;
  return 0;  
} 
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,如何期望我可以enum为 an 赋值int,但不能以其他方式赋值?

当然,这一切都可以在C.

c++

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

枚举类的向量的初始化列表问题

我有一个枚举,以及枚举的一些内容的几个向量.我想将枚举更改为枚举类,因为类型安全,但我收到错误.请考虑以下代码段:

#include <vector>

enum Colour {
        red,
        green,
        blue
};

int main() {
        const std::vector<Colour> something { red, green };
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.但是,如果我将枚举更改为枚举类,我会收到错误,例如error: ‘green’ was not declared in this scope.我能做什么?

c++ enums vector

3
推荐指数
1
解决办法
522
查看次数

枚举和枚举类之间的区别

谁能解释一下两者之间的区别

enum 
{Type1,type2}
Run Code Online (Sandbox Code Playgroud)

enum class
{Type1, type2}
Run Code Online (Sandbox Code Playgroud)

我经常使用前一个示例(可能过于频繁而又没有足够的封装),但是我从未使用过第二个示例。

谢谢

枚举

c++

2
推荐指数
1
解决办法
3452
查看次数

标签 统计

c++ ×9

enums ×6

bitflags ×1

c ×1

c++17 ×1

flags ×1

nested ×1

python-3.x ×1

scope ×1

swig ×1

vector ×1