首页 > 解决方案 > 在 C++ 中进行 N 阶乘编译时间的 3 种不同/相同方法

问题描述

我正在尝试使用模板元编程、constexpr 和 if constexpr,并提出了 3 种不同的方法来进行 N 递归/N 阶乘运算。

所有三个示例都是我在 SO 上或通过在网上搜索找到的 - 然后对其进行了修改,所以它们也是一样的

第一个示例是使用模板元编程:示例 1

template<int N>
struct NGenerator
{
    static const int result = N + NGenerator<N-1>::result;
};

template<>
struct NGenerator<0>
{
    static const int result = 1; 
};

static int example1 = NGenerator<5>::result;

第二个仍在使用模板,但我在示例 2中抛出了一个 constexpr

template<int N>
constexpr int example2() 
{
return N + example2<N - 1>();
}


template<>
constexpr int example2<0>() 
{ 
    return 1;
}

static int ex2 = example2<5>();

第三个,是我删除模板并“仅”使用 constexpr 的地方:示例 3

constexpr int generator(int n)
{
    return (n <= 1) ? 1 : n + generator(n - 1);
}

static int ex3 = generator(5);

在我看来,所有三个都做同样的事情 - 当输入数字是编译时间常数时。这三个都是递归的,所有三个都在编译时工作。

我的问题是——这三者有什么区别?哪一个最可取?

最后——我想实现“if constexpr”但没能实现,所以我的解决方法是在示例 3 中执行“if 语句”——这并不是真正的 if 语句,但是如果 - 如果它以任何方式相同,我可以得到最接近编译时间,我不确定。

标签: c++template-meta-programmingconstexprcompile-timeif-constexpr

解决方案


像这样的玩具例子不会有太大的不同。对于更复杂的示例,递归模板实例化实际上具有与所有模板实例化名称(包括参数)的长度之和成正比的内存成本。这真的很容易炸。

根据我的经验constexpr,函数往往编译得更快。

编译器可能会记住所有 3 个;但是 constexpr 非模板函数会喷出更少的符号(噪音)。

比所有这些更好的是带有循环的 constexpr 函数。

编译器可以在运行时自由地执行大多数选项,因为您不坚持编译时评估。替换static intconstexpr int


推荐阅读