类vs枚举类作为索引类型

Evg*_*Evg 5 c++ c++11 enum-class

P0138R2建议1开始

在现代C++ 11程序中引入一种几乎完全复制但又不同类型的新整数类型有一种非常有用的技术: enum class具有明确指定的底层类型.例:

enum class Index : int { };    // Note: no enumerator.
Run Code Online (Sandbox Code Playgroud)

可以使用Index一个新的不同整数类型,它没有隐式转换为任何东西(好!).

要转换Index为其基础类型,定义是很有用的

int operator*(Index index) {
    return static_cast<int>(index);
}
Run Code Online (Sandbox Code Playgroud)

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

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

     int operator*() const {
         return index_;
     }

private:  
     int index_;
};
Run Code Online (Sandbox Code Playgroud)

两者似乎都大致相同,可以以相同的方式使用:

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

bar(Index{1});

int i = 1;
bar(Index{i});
Run Code Online (Sandbox Code Playgroud)

Pro enum class:比较运算符是自动定义的,con enum class:enum class无法指定默认构造的索引值,它始终为零.

这些替代品之间是否存在其他实际差异?


1我换uint32_tint避免#include <cstdint>.

JVA*_*pen 1

我使用的强类型的替代方案是 Jonathan Boccara 的NamedTypes变体。他在博客上的多篇文章中很好地解释了所有详细信息,请参阅https://www.fluencecpp.com/2016/12/08/strong-types-for-strong-interfaces/

写起来稍微冗长一些:using Index = NamedType<int, struct IndexTag, Comparable, ImplicitlyConvertibleTo<int>>;

当你构造这个时,你需要编写类似的东西Index{0},但是,当你将它用作索引时,它应该自动转换为基础类型。

它有几个优点,包括能够处理任何类型。最大的缺点是它是您必须导入的外部库而不是内置功能。