通常,人们需要一起使用几种枚举类型.有时,一个人有一个名字冲突.我想到了两种解决方案:使用命名空间,或使用"更大"的枚举元素名称.仍然,命名空间解决方案有两种可能的实现:具有嵌套枚举的虚拟类或完整的命名空间.
我正在寻找这三种方法的优缺点.
例:
// 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) 在一些遗留代码中,我有很多枚举,以及一个巨大的切换案例.我想测试一下开关是否具有纯枚举类型.无意义的例子:
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或类似的工具可以做到这一点,我也会很开心.
我习惯使用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的首选方式?
我目前正在尝试提出一种巧妙的方法来实现标志,除了通常的“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 位。因此,虽然它可能不是必需的,但我想任何实现都应该很容易使用第 …
假设我们有
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 ++中的穷举枚举?
编辑:这个答案解决了问题,但最后我提出了一个更加模块化的解决方案。一探究竟 :)
我从两次 讨论中知道,为了类型安全,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) 为什么下面的代码编译没有任何错误?
enum class Enumeration;
void func()
{
auto enumeration = static_cast<Enumeration>(2);
auto value = static_cast<int>(enumeration);
}
Run Code Online (Sandbox Code Playgroud) #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
.
我有一个枚举,以及枚举的一些内容的几个向量.我想将枚举更改为枚举类,因为类型安全,但我收到错误.请考虑以下代码段:
#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
.我能做什么?
谁能解释一下两者之间的区别
enum
{Type1,type2}
Run Code Online (Sandbox Code Playgroud)
和
enum class
{Type1, type2}
Run Code Online (Sandbox Code Playgroud)
我经常使用前一个示例(可能过于频繁而又没有足够的封装),但是我从未使用过第二个示例。
谢谢
枚举