类与枚举类作为索引类型

Class vs enum class as an index type

本文关键字:索引 类型 枚举      更新时间:2023-10-16

P0138R2提案以1开头

有一种

非常有用的技术可以引入一种新的整数类型,该类型几乎是现代 C++11 程序中的精确副本,但又是不同的类型:一个enum class显式指定的基础类型。例:

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

可以将Index用作新的不同整数类型,它没有隐式转换为任何内容(好!

要将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的索引值,它始终为零。

这些替代方案之间还有其他实际差异吗?


1uint32_t更改为int以避免#include <cstdint>

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

写作稍微啰嗦一些:using Index = NamedType<int, struct IndexTag, Comparable, ImplicitlyConvertibleTo<int>>;

当你构造它时,你需要写一些类似Index{0}的东西,但是,当你把它用作索引时,它应该自动转换为底层类型。

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