【问题标题】:Map namespaced enum in a class在类中映射命名空间枚举
【发布时间】:2012-09-08 21:53:57
【问题描述】:

假设我有这样的代码:

namespace foo {
  enum bar
  {
    fooBarA,
    fooBarB
  };
}

struct baz
{
  // TODO: map "bar" in this struct to make valid:
  bar returnSomething() { return fooBarA; }
};

// and also this:
void doSomething()
{
  baz myBaz;

  if( baz::fooBarA == myBaz.returnSomething() )
  { /* ... */ }
}

我可以在 TODO 部分放置什么样的代码以使其余部分有效?一些usingtypedef

PS:为了避免关于“为什么”的问题:命名空间存在于它自己的头文件中,并且可能被几个不同的类使用,这些类应该同意 fooBarAfooBarB 的值,但也隐藏它它们基于foo,因为这与使用baz 的人无关。

PPS:允许使用 C++11。 enum class 有帮助吗?

PPPS:像using declaration with enum? 这样的其他问题处理枚举在类中而不是直接在命名空间中的情况。

【问题讨论】:

  • 是的,foo::bar 可以工作——但它不会让我向baz 的用户隐瞒bar 不是baz 的“成员”这一事实。或者换句话说,我希望bar 看起来像baz 的正式成员。

标签: c++ enums namespaces


【解决方案1】:

这种方式需要在 foo 命名空间中进行少量工作。但它对 foo::bar 的现有用户应该是透明的。只需将您的 foo::bar 的值包含在一些从中派生出您的 baz 类的结构中:

namespace foo {
  struct barValues
  {
    enum Values {
      fooBarA,
      fooBarB
   };
  };

  typedef barValues::Values bar;
  static const bar fooBarA = barValues::fooBarA;
  static const bar fooBarB = barValues::fooBarB;
}

struct baz : foo::barValues
{
  typedef foo::bar bar;
  bar returnSomething() { return fooBarA; }
};

// and also this:
void doSomething()
{
  baz myBaz;

  if( baz::fooBarA == myBaz.returnSomething() )
  { /* ... */ }
  if( foo::fooBarA == myBaz.returnSomething() )
  { /* ... */ }
}

与其他答案相比,它的优势在于您将 foo::bar 值包含在命名空间 foo 中 - 只有在那里您才能添加/修改/删除此枚举值。我相信这更安全。与其他答案相比,它的缺点是您必须修改其他无法选择的文件。

【讨论】:

  • 不是我希望的好解决方案,但可能是最好的解决方案。
  • 我在考虑这个 - 但找不到更好的东西。也许,如果以这种语法开头:namespace foo { struct bar { enum Values { A, B }; }; } 然后在任何地方都使用foo::bar::A - 但对于baz 使用baz::A。不确定是否更聪明,但不需要重新输入所有名称两次。
【解决方案2】:

这样就可以了

struct baz
{
    typedef foo::bar   bar;
    static const bar fooBarA = foo::fooBarA;
    static const bar fooBarB = foo::fooBarB;

  // This is now valid
  bar returnSomething() { return fooBarA; }
};

但我不知道它是否真的有用。如果您的用户试图重载某些功能或某些东西,他们可能会感到意外。

【讨论】:

  • 更糟糕的是引入了可维护性漏洞。当有人修改 foo::bar - baz 也必须更改。编译器会告诉我们减少或改变 foo::bar 的元素,但不会说扩展 foo::bar。
  • 这可行,但不太实用。想象一下bar 没有两个值,但可能有 100 种不同的颜色。然后使用该枚举的每个类都需要额外的 100 行定义值...
  • @Chris - 对,它不是很有用。另一方面,我不知道有什么方法可以“导入”枚举值而不单独提及每个值。它们是单独的价值观,而不是一个包。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 2013-11-20
  • 2014-07-24
  • 2016-03-27
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多