确保覆盖地图中的所有枚举值

时间:2014-11-05 22:20:58

标签: c++ enums

说我有以下内容:

#include <map>

enum class Thing {Zero, One, Two};

class Metadata {};

std::map<Thing, Metadata> extra_info;

void foo() {
    extra_info[Thing::Zero] = Metadata();
    extra_info[Thing::One] = Metadata();
    extra_info[Thing::Two] = Metadata();
}

如果添加了新标记,我希望确保在Thing中考虑extra_info的所有标记,例如Thing::Three

我认为最后总是有一个标记,LastTag,并从0迭代到LastTag - 2并验证地图中是否存在这些密钥,但这似乎很糟糕。在编译时完成此任务的方法最好,但我可以看到这根本不可能。

在C#中,使用反射来获取所有枚举值,然后迭代这些值是一件简单的事情。我认为它告诉我无法用C ++标签找到答案,但我可以找到Java和C#的答案......这让我觉得这是不可能的。< / p>

1 个答案:

答案 0 :(得分:1)

枚举中的Sentinel值已成为许多项目的一部分,用于指示枚举值的数量或用系统定义的用户可用枚举的范围界定。

在您的情况下,您可以利用地图具有唯一键并添加标记值(严格来说不是枚举的一部分)的事实:

enum class Thing { Zero, One, Two, Three, EndSentinel };

class Metadata {};

std::map<Thing, Metadata> extra_info;
typedef std::map<Thing, Metadata>::size_type map_type;

void foo() {
    // Can't forget these values
    extra_info[Thing::Zero] = Metadata();
    extra_info[Thing::One] = Metadata();
    extra_info[Thing::Two] = Metadata();
    extra_info[Thing::Three] = Metadata();
}

int main() {
    foo();

    assert(extra_info.size() == (map_type)Thing::EndSentinel);
}

Example