c++ - 使用枚举与变量,存储非类型模板参数值。 (在 Int2Type<int v> 模板中)

标签 c++ c++11

通过 Andrei Alexandrescu 的 Modern C++ Design,我无法理解使用未命名、无作用域的 enum 来存储非类型参数的原因。 为什么不直接使用变量。

有什么优点吗?

template <int v>
struct Int2Type
{
   enum { value = v }; //why not use int value = v; which compiles fine
};

额外(如果有帮助):该模板旨在用作“类型生成器”以在编译时选择不同的函数。

最佳答案

使用 enum 而不是 static const int 或 C++11 static constexpr int 的主要原因是 enum 给你 true prvalue,非常像字面量 int。当 ODR 问题出现时,这一点就变得很重要。

例如,下面的一段代码工作正常(完整示例):

void foo(const int& x) {
    std::cout << "X: " << x;
}

struct V {
    enum {value = 42; }
};

void bar() {
    foo(V::value);
}

另一方面,以下结构定义表现出未定义的行为(违反 ODR):

struct V {
    static const int value = 42;
    // same with static constexpr int value = 42;
};

这样做的原因是对值的绑定(bind)引用(调用 foo 时)ODR - 在它是 const 成员时使用值。必须定义所有 ODR 使用的变量。

但是,由于引用不能绑定(bind)到枚举成员(和文字),因此创建了一个临时对象,引用绑定(bind)到该临时对象,因此无需定义任何内容。这是一个非常有用的功能。

关于c++ - 使用枚举与变量,存储非类型模板参数值。 (在 Int2Type<int v> 模板中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57365439/

相关文章:

c++ - move 运算符=和复制运算符=之间的区别

c++ - Emscripten 的 CMake 项目

C++ 垃圾回收编译器

c++ - ASIO signal_set对多个IO线程不可靠,取决于代码顺序?

c++ - 如何在每个例程OpenMP中处理子数组

c++ - 使析构函数不是虚拟的,并在特殊情况下删除基指针是否安全?

c++ - Emscripten 崩溃与 mappedGlobals.find(name) != mappedGlobals.end()

c++ - 如何使 C++(共享)库与 clang 和 GCC 兼容?

C++:库导入错误 (‘stdin_fileno’ 未在此范围内声明)

c++ - 生成运算符的签名=()?