模板参数:enum, class 或 enum class

Template parameter: enum, class or enum class

考虑以下 class:

template <class Endianness>
class bitcode
{};

Endianness 可以是:default_endiannesslittle_endianbig_endian

问题如下:根据 C++14 和后续的 C++17,什么是 is/will 最佳和常见做法? (我所说的普通是指标准库或 boost 使用(或将使用)的那些。(+ 为什么?)

// The enum option
enum enum_endianness {default_endianness, little_endian, big_endian};

// The enum class option
enum class enum_class_endianness {default_endianness, little_endian, big_endian};

// The class option
class class_default_endianness{}; 
class class_little_endian{}; 
class class_big_endian{}; 

(注意:当然 bitcode 的声明将取决于首选选项。)

您必须选择适合您的目的:

  1. enum:主要是为了向后兼容。
  2. enum class: 需要事先知道所有标签才能使用
  3. class: 任何人都可以引入新的标签,你可以让标签包含数据。

选择有点受限,但如果您想将其用作模板参数(例如,对于您的 bitcode class 模板),我会坚持使用 class/struct 标签.这往往使模板编程比混合基于类型的模板和基于特定常量值的模板更简单。

enum class最合适。它是类型安全的范围枚举。您可以使用 == 运算符比较值,还可以使用模板参数应用模板特化和推导。

enum 本身就是一个 无作用域枚举 。这些通常被认为是与 C++98 和 C 的向后兼容功能。值将隐式转换为 int,但这些整数将毫无意义。

class 一个人就能 发送标签 。尽管这可行,但您将没有 ==!= 运算符,这可能会迫使您过度使用模板和重载。

另一个要考虑的模式是 type-traits 模式:class 包含静态数据成员和函数,因此您不必添加更多模板参数.

enum class endianness {little_endian, big_endian};

class little_endian_traits {
    static const enum endianness endianness = endianness::little_endian;
};

class big_endian_traits {
    static const enum endianness endianness = endianness::big_endian;
};

typedef little_endian_traits default_endian_traits; // depending on platform

template< class traits >
class bitcode;