5
\$\begingroup\$

I'm using C++11 and I have the following problem (pseudo C++):

template<typename T, R1 (*F1)(Args1...)>
class one_size_fits_them_all {};

template<typename T, typename U, typename V, R1 (*F1)(Args1...), R2 (*F2)(Args1...)>
class one_size_fits_them_all {};

template<typename T, typename U, R1 (*F1)(Args1...), R2 (*F2)(Args2...), R3 (*F3)(Args3...)>
class one_size_fits_them_all {};

So what I want to do is to overload the class by its template parameters and pass in function pointers.
I came up with this fully compile- and runnable solution:

// compile with `g++ -std=c++11 test.cpp`
#include <iostream>

#define CALLABLE(FUNCTION) callable<decltype(FUNCTION), FUNCTION>

template<typename Signature, Signature & S>
struct callable;

template<typename Return,
         typename ... Args, Return (&Function)(Args ...)>
struct callable<Return(Args ...), Function> {
  Return operator()(Args ... args)
  {
    std::cerr << __PRETTY_FUNCTION__ << std::endl;
    return Function(args ...);
  }
};

template<typename ... Arguments>
class one_size_fits_them_all;

// A generic template
template<typename T, typename U, typename V,
         typename F1, typename F2, typename F3>
class one_size_fits_them_all<T, U, V, F1, F2, F3>
{
  public:
    one_size_fits_them_all(void)
    {
      std::cerr << "generic one_size_fits_them_all" << std::endl
                << __PRETTY_FUNCTION__ << std::endl << std::endl;
      F1()();
      F2()();
      F3()();
      std::cerr << std::endl;
    }
};

// A specialized template
template<typename T, typename Callable>
class one_size_fits_them_all<T, int, int, void, void, Callable>
{
  public:
    one_size_fits_them_all(void)
    {
      std::cerr << "specialized one_size_fits_them_all" << std::endl
                << __PRETTY_FUNCTION__ << std::endl << std::endl;
      Callable()();
      std::cerr << std::endl;
    }
};

void f1(void)
{
  std::cerr << __PRETTY_FUNCTION__ << std::endl << std::endl;
}

void f2(void)
{
  std::cerr << __PRETTY_FUNCTION__ << std::endl << std::endl;
}

void f3(void)
{
  std::cerr << __PRETTY_FUNCTION__ << std::endl << std::endl;
}

int main(int argc, char ** argv)
{
  // generic template
  auto generic = one_size_fits_them_all<
    int, int, int, CALLABLE(f1), CALLABLE(f2), CALLABLE(f3)>();

  // specialized template
  auto specialized_int = one_size_fits_them_all<
    int, int, int, void, void, CALLABLE(f1)>();

  // specialized template
  auto specialized_double = one_size_fits_them_all<
    double, int, int, void, void, CALLABLE(f3)>();

  return 0;
}

My questions are:

  1. Is this a good solution?
  2. Can it be improved?
\$\endgroup\$
  • \$\begingroup\$ Why function pointers? Why not use function objects? \$\endgroup\$ – jliv902 Jan 17 '14 at 19:27
  • \$\begingroup\$ I intend to use this mainly for C functions (more specifically c style iterator function on PODs). If I got that function object thing right, I'd have to write a wrapper class for each of the C functions. \$\endgroup\$ – jrk Jan 18 '14 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.