如何在模板折叠表达式中使用 if constexpr?
How to use if constexpr in template fold expressions?
我想编写一个参数数量可变的求和函数,条件是它应该忽略不是 std::is_arithmetic
的参数
我找到了一个可行的递归版本
auto old_sum(){
return 0;
}
template<typename T1, typename... T>
auto old_sum(T1 s, T... ts){
if constexpr(std::is_arithmetic_v<T1>)
return s + old_sum(ts...);
else
return old_sum(ts...);
}
我想知道是否可以在 fold 表达式的上下文中使用 if constexpr
使以下代码仅考虑参数包中的算术类型:
template<typename... T>
auto fold_sum(T... s){
return (... + s);
}
由于我们没有三元运算符 constexpr
,我们可以使用 lambda 代替。
#include <type_traits>
template<typename... T>
constexpr auto fold_sum(T... s){
return (... + [](auto x)
{
if constexpr(std::is_arithmetic_v<T>) return x;
else return 0;
}(s));
}
用法:
int main()
{
static_assert(fold_sum(0, nullptr, 5, nullptr, 11, nullptr) == 16);
}
您绝对想使用 if constexpr
?
我提出了一个不同的替代方案:std::get()
和 std::pair
来模拟一个 constexpr
三元运算符,如下所示(经过 Vittorio Romeo 的改进;谢谢)
#include <utility>
#include <type_traits>
template<typename ... Ts>
constexpr auto fold_sum (Ts const & ... s)
{ return (... + std::get<std::is_arithmetic_v<Ts>>(std::pair{0, s})); }
int main ()
{
static_assert(fold_sum(0, nullptr, 5, nullptr, 11, nullptr) == 16);
}
我想编写一个参数数量可变的求和函数,条件是它应该忽略不是 std::is_arithmetic
我找到了一个可行的递归版本
auto old_sum(){
return 0;
}
template<typename T1, typename... T>
auto old_sum(T1 s, T... ts){
if constexpr(std::is_arithmetic_v<T1>)
return s + old_sum(ts...);
else
return old_sum(ts...);
}
我想知道是否可以在 fold 表达式的上下文中使用 if constexpr
使以下代码仅考虑参数包中的算术类型:
template<typename... T>
auto fold_sum(T... s){
return (... + s);
}
由于我们没有三元运算符 constexpr
,我们可以使用 lambda 代替。
#include <type_traits>
template<typename... T>
constexpr auto fold_sum(T... s){
return (... + [](auto x)
{
if constexpr(std::is_arithmetic_v<T>) return x;
else return 0;
}(s));
}
用法:
int main()
{
static_assert(fold_sum(0, nullptr, 5, nullptr, 11, nullptr) == 16);
}
您绝对想使用 if constexpr
?
我提出了一个不同的替代方案:std::get()
和 std::pair
来模拟一个 constexpr
三元运算符,如下所示(经过 Vittorio Romeo 的改进;谢谢)
#include <utility>
#include <type_traits>
template<typename ... Ts>
constexpr auto fold_sum (Ts const & ... s)
{ return (... + std::get<std::is_arithmetic_v<Ts>>(std::pair{0, s})); }
int main ()
{
static_assert(fold_sum(0, nullptr, 5, nullptr, 11, nullptr) == 16);
}