#include <memory>
#include <type_traits>

// Fluent syntax helper to binds service implementations and factory methods
template<typename TService> struct BindSyntax {

  // Placeholder for real service factory function pointer registration.
  typedef std::shared_ptr<TService>(*CreateServiceFunction)(int);
  CreateServiceFunction myFunction;

  // Define a factory method to provide the service
  // TODO: Can the compiler implicitly figure out the function's return type?
  template<typename TResult, std::shared_ptr<TResult>(*TMethod)(int)>
  void ToFactoryMethod() {
    static_assert(
      std::is_base_of<TService, TResult>::value, "Result must inherit service"
    );

    myFunction = [](int mooh) {
      return std::static_pointer_cast<TService>(TMethod(mooh));
    };
  }
};

// ------------------------------------------------------------------------- //

struct Base {};
struct Derived : public Base {};

// Example factory method
std::shared_ptr<Derived> exampleFactory(int) {
  return std::make_shared<Derived>();
}

int main() {
  BindSyntax<Base> bind;
  bind.ToFactoryMethod<Derived, exampleFactory>();
  
  // In the above call, I don't want to have to explicitly specify
  // 'Derived' as the return type of the method
}