Как функторы без параметров и функторы с типом возврата void? - PullRequest
0 голосов
/ 03 апреля 2019

Я видел этот хороший код . И хочу использовать его для моего случая.

Для этого я изменил направление, так что combine(f,g,h)(x) означает: do h(g(f(x))).

Но на самом деле я хочу:

до f(x).

Если есть результат y, тогда выполните g(y), в противном случае выполните g().

Если есть результат z, тогда выполните h(z), в противном случае сделайте h().

Итак, вот измененный код:

template<typename ... Fs>
struct combine_impl
{
    combine_impl(Fs&& ... fs) : functionTuple(std::forward<Fs>(fs) ...) {}
    static constexpr numberOfFs = sizeof ... (Fs);
    template<size_t N, typename ... Ts>
    auto apply(std::integral_constant<size_t, N>, Ts&& ... ts) const
    {
        return apply( std::integral_constant<size_t, N + 1>{}
                    , std::get<N>(functionTuple)(std::forward<Ts>(ts)...));
    }

    template<typename ... Ts>
    auto apply(std::integral_constant<size_t, numberOfFs -1>, Ts&& ... ts) const
    {
        return std::get<numberOfFs -1>(functionTuple)(std::forward<Ts>(ts)...);
    }

    template<typename ... Ts>
    auto operator()(Ts&& ... ts) const
    {
        return apply(std::integral_constant<size_t,0>{}, std::forward<Ts>(ts) ...);
    }

    std::tuple<Fs ...> functionTuple;
};

template<typename ... Fs>
auto combine(Fs&& ... fs)
{
    return combine_impl<Fs ...>(std::forward<Fs>(fs) ...);
}

Edit: Чтобы прояснить, что это был за вопрос: Пример:

struct FunctorA
{
   float operator()(int k) const {return k*2.5f;}
};


struct FunctorB
{
   float operator()(float k) const {return k*2.5f;}
};

void main()
{
   float result = combine(FunctorA(),FunctorB())(4);
}

отлично работает с кодом. Но я хочу иметь возможность использовать такой код:

struct FunctorA
{
   voidoperator()(int k) const 
   {
       // side effects
   }
};


struct FunctorB
{
   float operator()() const 
   {
      return 42.f;
   }
};

void main()
{
   float result = combine(FunctorA(),FunctorB())(4);
}

Это не скомпилируется из-за invalid use of void expression.

Edit: после некоторого чтения: это должно быть возможно с sfinae. Выражение

decltype(std::get<N>(functionTuple)(std::forward<Ts>(std::declval<Ts>())...))

имеет тип void, когда мне нужно использовать другую версию apply.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...