#include <iostream>

struct Test {
  template <typename T> static bool Function(T x) { return true; }
};

// Magical template alias
template <typename T> constexpr auto funky1 = &Test::Function<T>;

// lambda means it'll infer the template parameters when calling
auto funky = [](auto in) { return funky1<decltype(in)>(in); };

int main() {
  int x = 0;

  // Just use the `funky1` version, but you have to specify the template parameters
  std::cout << "string: " << funky1<std::string>("I'm a string") << std::endl
            << "int: " << funky1<int>(42) << std::endl
            << "bool: " << funky1<bool>(true) << std::endl;

  // Use the `funky` version, where template parameters are inferred
  std::cout << "string: " << funky("I'm a string") << std::endl
            << "int: " << funky(42) << std::endl
            << "bool: " << funky(true) << std::endl;

  return 0;
}