如何使用运算符来专门化模板?

时间:2019-12-06 06:34:29

标签: c++ templates

我想通过TMP将1到N-1的数字相加。因此我编写了如下所示的源代码,但是发生了错误template argument '(number - 1)' involves template parameter(s)。您碰巧知道如何处理吗?

template <int number, int i = 1>
class Sum {
    public:
        static const int result = i + Sum<number, i + 1>::result;
};

template <int number>
class Sum<number, number - 1> {
    public:
        static const int result = number - 1;
};

int main () {
    const int result = Sum<10>::result;
    return 0;
}

1 个答案:

答案 0 :(得分:1)

GCC仍然遵循the rule

  

非类型参数表达式不能使用模板参数的名称,除非它恰好是模板参数的名称。

要使用模板专业化解决问题,可以将第二个非类型模板参数包装到std::integral_constant中,使其成为类型模板参数:

template<int number, class i = std::integral_constant<int, 1>>
struct Sum {
    static constexpr int value = i() + Sum<number, 
       std::integral_constant<int, i() + 1>>::value;
};

template<int number>
struct Sum<number, std::integral_constant<int, number - 1>> {
    static constexpr int value = number - 1;
};

static_assert(Sum<10>::value == 45);

或者,您可以使用if constexpr并且不使用部分专业化:

template<int number, int i = 1>
struct Sum {
    static constexpr int value = [] {
        if constexpr (number == i + 1)
            return i;
        else 
            return i + Sum<number, i + 1>::value;
    }();
};

static_assert(Sum<10>::value == 45);

折叠表达式还提供了另一种方法:

template<class> struct Sum_impl;

template<int... numbers>
struct Sum_impl<std::integer_sequence<int, numbers...>> {
    static constexpr int value = (... + numbers);
};

template<int number>
struct Sum : Sum_impl<std::make_integer_sequence<int, number>> {};
相关问题