Как использовать, если constexpr в выражениях сгиба шаблона? - PullRequest
0 голосов
/ 14 декабря 2018

Я хотел бы написать функцию суммы с переменным номером аргумента с условием, что он должен игнорировать аргументы, которые не 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...);
}

Мне интересно, могу ли я использовать if constexpr в контексте выражения сгиба, чтобы следующий код рассматривал только арифметические типы из пакета аргументов:

template<typename... T>
auto fold_sum(T... s){
    return (... + s);
}

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Вы абсолютно хотите использовать if constexpr?

Я предлагаю другую альтернативу: std::get() и std::pair для имитации троичного оператора constexpr следующим образом (с улучшением Витторио Ромео; спасибо)

#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);
 }
0 голосов
/ 14 декабря 2018

Поскольку у нас нет троичного оператора constexpr, мы можем использовать вместо него лямбду.

#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);
}

живой примерна godbolt.org

...