在我的项目中,我有很多枚举,需要有与枚举成员相关的其他属性和与枚举类型相关的辅助静态方法.
据我所知,这对于标准枚举类MyItem {...}是不可能的,所以对于我项目中的每个枚举类,我有一个辅助类MyItemEnum,它封装了这些辅助静态方法,并且还实例化了辅助实例本身,以便我可以访问他们的方法,以获得其他属性.
Bellow一个例子(尽可能简化,但我相信所讨论的所有功能都在那里).
MyItem.h
enum class MyItem : unsigned int {
Item1 = 1,
Item2 = 5
};
class MyItemEnum {
private:
MyItem myItem;
size_t extInfo;
MyItemEnum(const MyItem& myItem, size_t extInfo);
~MyItemEnum();
public:
static MyItemEnum Item1;
static MyItemEnum Item2;
static const MyItemEnum &get(MyItem myItem);
operator MyItem() const;
size_t getExt() const;
bool hasNext() const;
MyItem next() const;
};
Run Code Online (Sandbox Code Playgroud)
我认为意思是显而易见的,我不需要在这里提供.cpp部分...当我需要访问扩展功能时,我使用MyItem作为参数在接口和MyItemEnum中传递.
我的第一个问题是,上面的方法是否正常,或者我应该考虑一些完全不同的东西?
我的第二个问题涉及我使用constexpr尝试做的这个枚举的优化:
enum class MyItem : unsigned int {
Item1 = 1,
Item2 = 5
};
class MyItemEnum {
private:
MyItem …Run Code Online (Sandbox Code Playgroud) 当我尝试编译以下代码时发生编译器错误:
for(binary_instructions_t &inst: BinaryInstructions){
}
Run Code Online (Sandbox Code Playgroud)
BinaryInstructions 是这个枚举类:
typedef unsigned int binary_instructions_t;
enum class BinaryInstructions : binary_instructions_t
{
END_OF_LAST_INSTR = 0x0,
RESET,
SETSTEP,
START,
STOP,
ADD,
REMOVE,
};
Run Code Online (Sandbox Code Playgroud)
我应该被允许使用枚举类中的项目来"循环"基于循环吗?或者我在该范围内巧妙地误解了基于循环是用于搜索数组的内容而不是像枚举类这样的东西?
我也尝试过:在实例中创建实例并进行搜索:
BinaryInstructions bsInstance;
for(binary_instructions_t &inst : bsInstance){
}
Run Code Online (Sandbox Code Playgroud)
但没有雪茄......提前谢谢,
我有一个这样的枚举:(实际上,它是一个枚举类)
enum class truth_enum {
my_true = 1,
my_false = 0
};
Run Code Online (Sandbox Code Playgroud)
我希望能够将my_true公开给全局命名空间,以便我可以这样做:
char a_flag = my_true;
Run Code Online (Sandbox Code Playgroud)
或至少:
char a_flag = (char)my_true;
Run Code Online (Sandbox Code Playgroud)
而不是这个:
char a_flag = truth_enum::my_true;
Run Code Online (Sandbox Code Playgroud)
这可能吗?
我尝试过这样的事情:
typedef truth_enum::my_true _true_;
Run Code Online (Sandbox Code Playgroud)
我收到错误:枚举类中的my_true,truth_enum没有命名类型
我的猜测是my_true是一个不是类型的值.有没有其他方法可以在我的程序中启用此功能?
不理想,但我可以这样做:
enum class : const char { ... };
const char const_flag_false = truth_enum::my_false;
Run Code Online (Sandbox Code Playgroud) enumeration cannot be a template是当我尝试使用BCC64(基于 Clang)编译以下代码时给出的错误:
template <typename T> enum class fooEnum : T
{
a,b,c,d,e
};
Run Code Online (Sandbox Code Playgroud)
起初,我认为这个明确的禁止是由于enum底层类型限制,如果枚举底层类型可以被模板化,那么它可能会导致格式错误的枚举,但是当我们尝试这样做时:
template <typename A> struct fooClass
{
enum class fooEnum : A
{
a,b,c,d,e
};
};
Run Code Online (Sandbox Code Playgroud)
只要A类型遵循与枚举底层类型相同的限制,它就可以毫无问题地编译,您知道,定义枚举值的表达式:
char或 一个signed/unsigned整数类型兼容。如果我们不遵循此规则,(使用类内枚举或全局枚举)会出现另一个特定错误,正如预期的那样:
enum class fooEnum : fooClass
{
a,b,c,d,e
};
Run Code Online (Sandbox Code Playgroud)
非整数类型“fooClass”是无效的基础类型
所以,这就是为什么我想知道为什么即使已经控制了底层类型,也明确禁止创建模板枚举。标准上哪里提到了这个禁令?
感谢您的关注。
请考虑以下示例:
struct ConvertibleStruct {};
enum class ConvertibleEC {};
struct Target {
// Implicit conversion constructors
Target(ConvertibleStruct) {}
Target(ConvertibleEC) {}
};
Target operator~(const Target& t) {
return t;
}
Target anotherFunction(const Target& t) {
return t;
}
int main() {
ConvertibleStruct t;
ConvertibleEC ec;
~t; // 1. Works finding the operator overloaded above
~ec; // 2. Fails to compile on clang 3.4 and gcc 4.8.2
operator~(ec); // 3. Works finding the operator overloaded above
anotherFunction(ec); // 4. Works
}
Run Code Online (Sandbox Code Playgroud)
编译器版本:
以上调查结果适用于 …
c++ operator-overloading implicit-conversion c++11 enum-class
我在一个项目中遇到了这种情况,其中我们有一些套接字通信,主要为流量控制交换字符。我们将这些字符转换为enum class : char一个开关。我想知道,如果另一端发送的字符不在我们的枚举类中,会发生什么。
我有这个 mwe:
enum class Foo : char {
UNKNOWN,
ENUM1 = 'A',
ENUM2 = 'B',
ENUM3 = 'C'
};
char bar1() {
return 'B';
}
char bar2() {
return 'D';
}
int main() {
switch((Foo)bar1()) {
case Foo::UNKNOWN:std::cout << "UNKNWON" << std::endl;break;
case Foo::ENUM1:std::cout << "ENUM1" << std::endl;break;
case Foo::ENUM2:std::cout << "ENUM2" << std::endl;break;
case Foo::ENUM3:std::cout << "ENUM3" << std::endl;break;
default:std::cout << "DEFAULT" << std::endl;break;
}
switch((Foo)bar2()) {
case Foo::UNKNOWN:std::cout << "UNKNWON" << std::endl;break; …Run Code Online (Sandbox Code Playgroud) 使用以下代码,我可以在编译时检查类型 E 是否为枚举:
static_assert(true == std::is_enum<E>::value, "Must be an enum");
Run Code Online (Sandbox Code Playgroud)
我如何检查它是否是一个enum class?
在这里他们建议添加 check !std::is_convertible<T, int>::value,但它看起来像一个技巧。有没有更好的办法?
我通常使用clang我可以使用的所有合理警告来开发代码(-Wall -Wextra [-Wpedantic])。这种设置的switch好处之一是编译器会检查与所使用的枚举相关的stataments的一致性。例如在这段代码中:
enum class E{e1, e2};
int fun(E e){
switch(e){
case E::e1: return 11;
case E::e2: return 22; // if I forget this line, clang warns
}
}
Run Code Online (Sandbox Code Playgroud)
clang会抱怨(警告)如果: 我省略了e1或e2案例,并且没有默认案例。
<source>:4:12: warning: enumeration value 'e2' not handled in switch [-Wswitch]
switch(e){
Run Code Online (Sandbox Code Playgroud)
这种行为很好,因为
default我不会做任何好事的人为案例。int,它可能是一个没有默认构造函数的类型。(请注意,我使用的是 ,enum class所以我只假设有效的情况,因为无效的情况只能由调用者端的讨厌的强制转换生成。)
现在坏消息是: 不幸的是,当切换到其他编译器时,这很快就会崩溃。在 GCC 和 Intel (icc) 中,上面的代码警告(使用相同的标志)我不是从非 void 函数返回。
<source>: …Run Code Online (Sandbox Code Playgroud) 我在 SO 上搜索了一下,很惊讶我没有找到任何类似的问题。如果已经回答了任何提示,我们很高兴。
我有一个定义了很多枚举类的代码库。其中一些指定了 totalNum 常量,例如
enum class Foo : int
{
a,
b,
c,
totalNum
}
Run Code Online (Sandbox Code Playgroud)
其他人没有这样的
enum class Bar : bool
{
oneOption,
otherOption
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个基本上像这样的功能
template <class EnumClassType>
EnumClassType typeToEnum (typename std::underlying_type<EnumClassType>::type value)
{
// If you hit this assertion, the value is outside of the valid enum range
assert (isPositiveAndBelow (value, decltype (value) (EnumClassType::totalNum)));
return EnumClassType (value);
}
Run Code Online (Sandbox Code Playgroud)
虽然这对totalNum指定的枚举有效并且有意义,但我想跳过这个断言,以防枚举中没有这样的标识符。有没有办法做到这一点?代码库目前使用 C++ 14,但由于即将进行的编译器更改,也欢迎使用 C++ 17 解决方案。
不幸的是,我发现迭代常规 s 的所有标准技术enum都不适用于enum classes,因为枚举类不会隐式转换为整数。
不是如何迭代枚举?,因为我询问的是 an enum class(即:强类型枚举),而他们询问的是常规enum(即:弱类型枚举)。