C++默认枚举值用法

ell*_*ial 6 c++ enums default-value

这个讨论是关于默认值的名称: C#:枚举的默认值应该是None还是Unknown?

然而,我最近与之交谈过的大量人认为默认值是有害的,不必要的,并可能导致不良做法.

举个例子考虑以下内容:

enum eJobStates
{
    JOB_STATE_INITIALISING,
    JOB_STATE_PROCESSING,
    JOB_STATE_DONE
};
Run Code Online (Sandbox Code Playgroud)

对于一个工作来说,JOB_STATE_UNKNOWN是没有意义的,但你可以想象任何可能用于监控所述工作的结构都可以使用这样的价值.

在定义枚举时是否有关于创建默认值的最佳实践/经验法则?是否应尽可能不惜一切代价避免它们?

Tom*_*err 2

无效的默认值基本上是设计中的一个变体。该对象在创建时无效。当合理的时候你应该避免这种情况。您绝不应该“不惜一切代价”避免它。

有些问题需要您从变体状态开始。在这种情况下,您必须在心理上推理该无效值。如果你避免命名它,你就会主动降低你的代码的表现力。从您和稍后必须维护代码的人之间的沟通角度来考虑。

顺风处理它很烦人。你一开始处于一个变体状态,但到了相关的时候,你希望它不再是变体。我更喜欢的策略是允许用户忽略变体状态,并在我犯错误时抛出。

namespace FooType {
  enum EnumValue {
    INVALID = 0
    ,valid
  };
}

struct Foo {
  Foo() : val(FooType::INVALID) {}
  FooType::EnumValue get() const {
    if (val == FooType::INVALID)
      throw std::logic_error("variant Foo state");
    return val;
  }
  FooType::EnumValue val;
};
Run Code Online (Sandbox Code Playgroud)

这使您的用户不必对您的差异进行推理,这是值得为之奋斗的。

如果你无法摆脱这一点,我通常更愿意降级为安全和不安全的接口。

struct Foo {
  Foo() : val(FooType::INVALID) {}
  bool get(FooType::EnumValue& val_) const {
    if (val == FooType::INVALID)
      return false;
    val_ = val;
    return true;
  }
  FooType::EnumValue get() const {
    FooType::EnumValue val_;
    if (!get(val_))
      throw std::logic_error("variant Foo state");
    return val_;
  }
  FooType::EnumValue get_or_default(FooType::EnumValue def) const {
    FooType::EnumValue val_;
    if (!get(val_))
      return def;
    return val_;
  }
  FooType::EnumValue val;
};
Run Code Online (Sandbox Code Playgroud)

此类接口适用于数据库等可能需要空值的情况。