Home > Enterprise >  Can you achieve fn(x1 ^ fn(x0)) with a fold expression?
Can you achieve fn(x1 ^ fn(x0)) with a fold expression?

Time:10-16

Is it possible to achieve the following using a fold expression?

template<class... Args>
auto foo(Args... args)
{
    //calling foo(x0, x1, x2) should be exactly equivalent to
    //calling fn(x2 ^ fn(x1 ^ fn(x0)))
}

CodePudding user response:

If you insist on a fold expression, something along these lines could probably be made to work (not tested):

template <typename T>
struct Wrapper {
  T& val;
};

template <typename T, typename U>
auto operator^(Wrapper<T> l, Wrapper<U> r) {
  return Wrapper(r.val ^ fn(l.val));
}

template<class... Args>
auto foo(Args... args)
{
  return f((... ^ Wrapper<Args>(args)).val);
}

CodePudding user response:

You could add a mandatory argument to foo and check if you've got additional arguments with a constexpr-if inside:

#include <utility>

template <class T, class... Args>
auto foo(T&& x, Args&&... args) {
    if constexpr (sizeof...(args))
        return fn(x ^ fn(foo(std::forward<Args>(args)...)));
    else
        return fn(x);
}

This requires that you reverse the arguments when calling the function though:

  • foo(x2, x1, x0) => fn(x2 ^ fn(x1 ^ fn(x0)))

Demo

  • Related