我正在写一个小的变元求和函数(使用c20,但我的问题在c17语法下仍然是一样的)。我希望让下面的代码尽可能简短和清晰(但不使用折叠表达式。这只是一个玩具问题,但在以后的应用程序中我希望避免使用折叠表达式):
Additive auto sum(Additive auto&& val, Additive auto&&... vals) {
auto add = [](Additive auto&& val1, Additive auto&& val2) {
return val1 + val2;
}; // neccessary??
if constexpr(sizeof...(vals) == 1) {
return add(val, std::forward<decltype(vals)>(vals)...); // (1)
//return val + std::forward<decltype(vals)>(vals)...; // (2)
}
else return val + sum(std::forward<decltype(vals)>(vals)...);
}
使用第(1)行,上面的代码可以编译,但是它需要'add' lambda的定义。然而,第(2)行不能编译,我得到了下面的gcc错误:* 参数包没有用'...'* 展开。如果我在第(2)行的std::forward表达式两边加上括号,我会得到以下错误:* 在“)”标记 * 之前需要二元运算符。
有没有办法把长度为1的参数包传递给操作符?
3条答案
按热度按时间qnakjoqk1#
拥抱negative thinking的力量,从零而不是一开始归纳:
上面的定义有一个副作用,
sum(x)
现在将编译并返回x
。(实际上,您甚至可以通过让该函数返回零来使该函数使用 no 参数工作,但问题随之而来:为了避免出现这种情况,我没有定义这个例子。)如果你坚持sum
只能从arity 2开始定义,你可以使用下面的方法:然而,只要有意义,你就应该允许使用“vacuous”格:它使代码更简单、更通用。注意例如在后一个定义中加法运算符出现了两次:这实际上是在两种情况之间复制折叠逻辑(在这种情况下,它只是一个加法,所以相对简单,但对于更复杂的运算,它可能会更麻烦),而处理退化情况通常是微不足道的,不会复制任何东西。
(我省略了概念注解,因为它们似乎与主要问题并不特别相关。)
puruo6ea2#
?
题外话:由于不确定Op的真实的需求,我偶然地快速设计了一个我一直在思考的东西。
〉_〈
zzoitvuj3#
您可以将一个项目解包到一个变量中并使用该变量: