类 vs 枚举类作为索引类型

8

P0138R2提案1开头。

There is an incredibly useful technique for introducing a new integer type that is almost an exact copy, yet distinct type in modern C++11 programs: an enum class with an explicitly specified underlying type. Example:

enum class Index : int { };    // Note: no enumerator.

One can use Index as a new distinct integer type, it has no implicit conversion to anything (good!).

Index 转换为其基础类型时,定义以下内容可能很有用:

int operator*(Index index) {
    return static_cast<int>(index);
}

创建 Index 类型的另一种方法是使用旧的 class

class Index final {
public:
     explicit Index(int index = 0) : index_(index) { }

     int operator*() const {
         return index_;
     }

private:  
     int index_;
};

两者似乎在很大程度上是等同的,可以以相同方式使用:

void bar(Index index) {
    std::cout << *index;
}

bar(Index{1});

int i = 1;
bar(Index{i});
enum class的优点:比较操作符自动定义,enum class的缺点:无法指定默认构造的enum class的索引值,它总是零。
这些替代方案还有其他实际差异吗?
注1:我将uint32_t更改为int,以避免使用#include <cstdint>

你的 operator* 应该返回一个引用吗? - Rakete1111
1
@Rakete1111(已编辑)对于类版本,这是可行的,但对于枚举版本则不可能。 - user743382
我删除了第二个问题。 - Evg
"enum class"是更简单的解决方案,所以我会选择它。为什么默认值如此重要? - zett42
一个缺点是:对于enum class,您无法定义转换或赋值运算符。 - geza
显示剩余3条评论
1个回答

1
我使用的强类型替代方案是Jonathan Boccara的NamedTypes的变体。他在博客的多篇文章中很好地解释了所有细节,请参见https://www.fluentcpp.com/2016/12/08/strong-types-for-strong-interfaces/
它的编写略微冗长:using Index = NamedType<int, struct IndexTag, Comparable, ImplicitlyConvertibleTo<int>>; 当您构造它时,需要编写类似Index{0}的内容,但一旦将其用作索引,它应自动转换为底层类型。
它具有几个优点,包括能够适用于任何类型。最大的缺点是它是一个外部库,您必须导入它,而不是内置功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接