c++ - 元编程中的枚举值与静态常量

标签 c++ template-meta-programming

我正在阅读《C++ 模板:完整指南》第 23 章“元编程”。最后,它描述了 在元编程中使用枚举值与静态常量的区别。考虑以下两种计算 3 的 N 次方的实现:

枚举实现:

// primary template to compute 3 to the Nth
template<int N>
struct Pow3 {
   enum { value = 3 * Pow3<N-1>::value };
};

// full specialization to end the recursion
template<>
struct Pow3<0> {
   enum { value = 1 };
};

静态常量实现:

// primary template to compute 3 to the Nth
template<int N>
struct Pow3 {
   static int const value = 3 * Pow3<N-1>::value;
};
// full specialization to end the recursion
template<>
struct Pow3<0> {
   static int const value = 1;
};

紧接着它说后一个版本有一个缺点。如果我们有一个函数 void foo(int const&);并将元程序的结果传递给它:foo(Pow3<7>::value);书上说:

A compiler must pass the address of Pow3<7>::value, and that forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure “compile-time” effect. Enumeration values aren’t lvalues (i.e., they don’t have an address). So, when we pass them by reference, no static memory is used. It’s almost exactly as if you passed the computed value as a literal.

说实话,我根本不明白他们的解释。我认为在静态常量版本中,我们在编译时评估结果,但实际引用发生在运行时,因为我们需要传递地址。但是我在前一种情况(枚举实现)中没有看到太大的区别,因为我们应该在那里进行临时物化(prvalue -> xvalue 转换),并且由于临时对象也有地址,所以我的思考过程失败了。它还说“不使用静态内存”,我也不明白,因为静态内存应该指的是编译时发生的分配。

有人可以更详细地解释整个事情吗?

最佳答案

(enum implementation) because we should have temporary materialization there (prvalue -> xvalue conversion) and since temporary objects also have the address

确实如此,但临时 xvalue 仅在函数调用期间存在。它与向函数传递整数文字相同。因此,可寻址对象在运行时临时存在,具有自 Action 用域。

相反,

... that forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure “compile-time” effect.

这个static const int是一个带有 static 的对象储存期限。不需要临时物化,它是一个对象,在程序启动时就存在,并且您正在引用它。

如果您编写多个 .cpp 文件,其中包括带有 Pow3 的 header ,他们都打电话 foo(Pow3<3>) :

  • enum版本将发出类似 foo(27) 的内容在每个翻译单元中,具有三个不相关的临时 xvalue
  • static version 将发出一个相当于 const int Pow3<3>::value = 27; 的全局对象并且每个翻译单元都会引用(即引用)同一个对象

关于c++ - 元编程中的枚举值与静态常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67317324/

相关文章:

c++ - 将重载的成员函数传递给函数模板

c++ - 可变参数模板可以匹配非可变参数模板吗?

c++ - 带模板的 N 维嵌套元循环

c++ - 在 Qt 中正确实现自定义 QWidget

android - logcat 中的回溯不完整

c++ - C++ 中的延迟评估包装类?

c++ - 使用不包括基类的模板从 C++ 列表中查找特定类型

C++/QT : "run" a QAction

c++ - std::ofstream,写入前检查文件是否存在

c++ - 比较 list<string> 和 vector<string> 中的字符串元素