C++ 该模板如何在运行时递归上实现编译时优化?
我了解一个众所周知的例子,即使用模板创建编译时阶乘计算,这样就不需要递归运行时计算。在这样的示例中,计算所需的所有值在编译时都是已知的 但我遇到了另一个使用模板计算数字幂的例子,我不明白这是如何对类似的运行时递归函数进行优化的:C++ 该模板如何在运行时递归上实现编译时优化?,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我了解一个众所周知的例子,即使用模板创建编译时阶乘计算,这样就不需要递归运行时计算。在这样的示例中,计算所需的所有值在编译时都是已知的 但我遇到了另一个使用模板计算数字幂的例子,我不明白这是如何对类似的运行时递归函数进行优化的: template<int n> inline int power(const int& m) { return power<n-1>(m)*m;} template<> inline int power<1>(c
template<int n>
inline int power(const int& m) { return power<n-1>(m)*m;}
template<>
inline int power<1>(const int& m) { return m;}
template<>
inline int power<0>(const int& m) { return 1;}
cout << power<3>(m)<<endl;
模板
内联整数幂(const int&m){返回幂(m)*m;}
模板
内联整数幂(const int&m){return m;}
模板
内联整数幂(const int&m){return 1;}
cout不同之处在于,此代码必须在编译时实例化,这可能会让优化人员有更好的机会注意到它只是一个很长的乘法序列
这实际上主要是关于Optimizer实现的猜测。它在内联不同的模板实例化(因为模板通常就是这样使用的)方面可能比
在内联递归(需要静态地发现停止条件)或展开循环时。只有在编译时同时知道X
和Y
时,才能获得模板元编程的优势。示例代码:
template<unsigned int X, unsigned int N>
struct Power { static const unsigned int value = X * Power<X,N-1>::value; };
template<unsigned int X>
struct Power<X,0> { static const unsigned int value = 1; };
模板
结构幂{static const unsigned int value=X*Power::value;};
模板
结构幂{static const unsigned int value=1;};
用法:Power::value
用于确定X^Y
.
在您发布的代码中(碰巧使用了模板
s而不是元编程!),编译时只知道Y
,而X
作为运行时参数传递。这意味着结果也将在运行时计算,我们必须依靠基于编译器的优化。最好在这种情况下使用。这只是一个执行运行时计算的语法糖。就我个人而言,我看不到任何性能提升。一种可能性是,不断的折叠允许内联深度降低到一个常数和一个简单的赋值,谢谢;与大家可能都知道的factorial示例相比,factorial实际上完全是在编译时计算的,因此不需要运行时计算factorial,在这种情况下,模板有一个更明显的好处,这可能吗?@Fellowshee阶乘也只能在编译时计算,如果它是编译时值的阶乘。正如您可以修改此函数模板以仅计算编译时值的能力一样。太棒了!我假设术语“元编程”仅适用于完全避免特定任务的运行时成本的情况?因此,为什么这个术语不适用于我的示例,而适用于您的示例?@Fellowshee,是的,在template
metaprogramming(TMP)的上下文中,您不应该有运行时成本。在您的示例中,您依赖于运行时传递的参数m
。在我的示例中,我们有一个编译时常量值
。一个好的测试是使用任何代码计算的答案作为template
参数,例如template struct X{}代码>;如果代码X<{您的计算}>X代码>编译比使用TMP好,否则不会。例如,我的代码X代码>编译良好。