使用模板元编程计算阶乘

Laz*_*zer 22 c++ templates metaprogramming

我不明白这段代码(来自维基百科)是如何工作的:

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}
Run Code Online (Sandbox Code Playgroud)
  • 这个奇怪的模板是<int N>什么?
  • 这是第二个奇怪的模板是<>什么?
  • 有什么东西 enum
  • 使用此而不是正常的运行时因子计算有什么好处?
  • 你们多久使用一次这个?我一直在使用C++,但之前从未使用过.我错过了C++的一小部分?

谢谢!

Ben*_*oît 25

  • 这个奇怪的模板是<int N>什么?

在C++中,模板参数可以是类型(前缀为classtypename)或整数(前缀为intunsigned int).这是我们的第二种情况.

  • 这第二个奇怪的是template <>什么?

template<> struct Factorial<0>是Factorial类模板的完全专业化,这意味着它0被认为是一个特殊的值,它对应于它自己的Factorial版本.

  • 什么是枚举?

枚举是在元编程C++中计算值的方法

  • 使用此而不是正常的运行时因子计算有什么好处?

首先创建此代码的原因是创建一个概念证明,可以使用元编程来完成微积分.优点是生成的代码非常有效(调用Factorial<4>::value等同于在代码中简单地写"24".

  • 你们多久使用一次这个?我一直在使用C++,但之前从未使用过.我错过了C++的一小部分?

使用这种方法很少能实现这种功能,但现在越来越多地使用元编程.请参阅Boost元编程库以获得可以执行的操作的提示.

  • 非类型模板参数不限于整数.它们可以是任何整数或枚举类型,指向对象或指向函数的指针,对对象的引用或对函数的引用,或指向成员的指针. (8认同)
  • "调用Factorial <4> :: value相当于调用一个简单返回24的函数"实际上它比函数调用的开销更小.它相当于使用已定义为24的枚举值,这基本上等同于直接写入`int value = 24;`. (4认同)
  • @R Samuel:你忘记了模板.有模板模板参数. (2认同)

utn*_*tim 6

这个奇怪的模板是 <int N>什么?

可以对类/类型,值和指针进行模板声明.您通常不会看到此表单,因为定义模板很少使用模板参数中的常量.

什么是第二个奇怪的模板<>?

考虑模板的最佳方法是执行与编译器类似的操作:将模板视为一个类,将模板参数替换为该类型的实际值.

那就是:

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};
Run Code Online (Sandbox Code Playgroud)

Factorial<2>::value 相当于:

// generated by the compiler when Factorial<2>::value is encountered in code:
struct Factorial2 { enum { value = 2 * Factorial1::value }; };
struct Factorial1 { enum { value = 1 * Factorial0::value }; };
// not generated by compiler, as it was explicitly defined in the code you ask about:
template <> struct Factorial<0> { enum { value = 1 }; }; // defines Factorial<0>
Run Code Online (Sandbox Code Playgroud)

什么是枚举?

它们value在编译时使用const定义枚举,允许您编写类似于示例中的客户端代码.

使用此而不是正常的运行时因子计算有什么好处?

优点是效率.由于在编译时扩展了值计算,因此运行时成本Factorial<10>::value与Factorial <1> :: value相同.在编译的代码中,它们都是常量.如果要在性能关键代码中计算阶乘,并且在编译时知道它是哪个值,则应该执行此操作,或者离线计算它并在代码中使用预先计算的值定义常量.

你们多久使用一次这个?

"this"你指的是一个常量的递归计算吗?如果是这样,不经常.

"this"是模板中常量的定义吗?常常 :)

"this"是特定类型模板的特殊化吗?非常非常非常.我知道std :: vector在一些STL实现中有一个完全独立的实现(一个std::vector<bool>8个元素不需要超过1个字节来存储值).

我一直在使用C++,但之前从未使用过.我错过了C++的一小部分?

不一定很重要.如果你使用boost,你使用的代码很可能是用这样的东西实现的.