#include <iostream>
using namespace std;

struct shr {
  template <typename A, typename B>
  constexpr auto operator()(A&& a, B&& b) {
    return std::forward<A>(a) >> std::forward<B>(b);
  }
};

struct shl {
  template <typename A, typename B>
  constexpr void operator()(A&& a, B&& b) {
    std::forward<A>(a) << std::forward<B>(b);
  }
};

template <typename F, typename A, typename B = A>
auto Apply(A&& a, B&& b) {
  return F{}(std::forward<A>(a), std::forward<B>(b));
}


int main() {
  // std::cout << (2 >> 1); but uglier
  Apply<shl>(std::cout, Apply<shr>(2, 1));
}