I need a template function:
template <typename ...Signatures, typename ...Functions>
auto make_callable_object (Functions&& ...functions);
that will return a callable object. When that callable object is called with any of the signature from Signatures, the correspondent functions from Functions should be called.
E.g.:
auto co = create_callable_object<void (int), void (std::string), void (std::exception)> (
             [] (int i) { std::cout << "int"; },
             [] (std::string) { std::cout << "string"; }
             [] (std::exception) { std::cout << "exception"; }
          );
should return an object that is equivalent to
struct { 
  void operator() (int) const { std::cout << "int"; }
  void operator() (std::string) const { std::cout << "string"; }
  void operator() (std::exception) const { std::cout << "exception"; }
};
I created some implementation, but it does not compile with clang c++11.
I'm not sure if there is compiler bug or bug in my code. I'm looking for workarounds or may be a better solution, that would compile with both gcc and clang in c++11 mode.
#include <iostream>
#include <tuple>
#include <type_traits>
#include <functional>
#define noexcept
#define constexpr
#define constexpr14
struct callable_impl_base {
  // will trigger if called with bad signature
  template <typename ...Ts>
  void operator() (Ts...) const { throw std::bad_function_call {}; }
};
template <typename Func, typename Base, typename Sig>
struct callable_impl;
template <typename Func, typename Base, typename R, typename ...Args>
struct callable_impl<Func, Base, R (Args...)>: public Base
{
  template <typename FF>
  constexpr callable_impl (FF&& f, Base&& b)
    : Base (std::forward<Base> (b))
    , func (std::forward<FF> (f))
  {
  }
  // unhiding method from the base classes.
  using Base::operator();
  constexpr R operator() (Args&& ...args) const
  {
    return func (std::forward<Args> (args)...);
  }
  constexpr14 R operator() (Args&& ...args)
  {
    return func (std::forward<Args> (args)...);
  }
  Func func;
};
template <typename Sig, typename Func, typename Base>
constexpr
callable_impl<
    typename std::decay<Func>::type
  , typename std::decay<Base>::type
  , Sig
>
make_callable_impl (Func&& func, Base&& base)
{
  return { std::forward<Func> (func), std::forward<Base> (base) };
}
// Recursion stopper.
template <typename ...>
constexpr callable_impl_base 
make_callable () { return {}; }
// Strip first Sig and first Func one by one.
template <typename Sig, typename ...Sigs, typename F, typename ...Fs>
constexpr14 auto
make_callable (F&& f, Fs&& ...fs)
   -> decltype (make_callable_impl<Sig> (
        std::forward<F> (f),
        make_callable<Sigs...> (std::forward<Fs> (fs)...)))
{
  static_assert (sizeof... (Sigs) == sizeof... (Fs), "bad number of args");
  return make_callable_impl<Sig> (
      std::forward<F> (f),
      make_callable<Sigs...> (std::forward<Fs> (fs)...));
}
using namespace std;
struct A {};
struct B {};
int main ()
{
  auto x = make_callable<void (const A&), void(B const&), void(int,int,int)> (
                [] (A const&) {cout << "A\n";},
                [] (B const&) {cout << "B\n";},
                [] (int,int,int) { cout << "int,int,int\n"; }
  );
  x (B{});
  x (A{});
  x (1,2,4);
  // this must throw because of incompatible signature.
  try {
    x (1,2);
  }
  catch (std::bad_function_call)
  {
      std::cout << "x (1,2) -> got exception (ok)\n";
  }
}
UPDATE:
I tried another solution and get rid of explicit signatures in make_callable template parameters. So, the compose function now is called in such easy way:
int main ()
{
  using namespace std;
  auto co = make_callable (
       [] (int) { cout << "int\n"; },
       [] (string) { cout << "string\n"; },
       [] (int,int) { cout << "int,int\n"; }
  );
  cout << "co(\"str\") -> "; co ("fff");
  cout << "co(55) -> "; co (55);
  cout << "co(55, 44) -> "; co (55, 44);
  // This must throw exception.
  try { co ('c', 4, 4); }
  catch (bad_function_call) { cout << "co('c',4,4) -> exception (ok)\n"; }
}
And here is Coliru Demo. But I still not sure if it is quite effective or some much better solution is possible.
 
    