我想通过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;
}
答案 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>> {};