15

Is it possible to achieve something like this:

template<typename Signature>
class Test
{
    public:
        //here I want operator () to respect the signature
};

Test<void(int)>          t1; //void operator()(int)
Test<void(int, float)>   t2; //void operator()(int, float)

Return type is always void.

I want to send as template parameter the function signature. Is this possible? I can't use variadic templates as my compiler doesn't support this feature yet.

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • what is it that you are trying to do? You can instantiate a template with a function signature, the problem would be the parameters when executing the function. See for example: `boost::bind`. – Nim Jan 21 '13 at 15:09

2 Answers2

18

With variadic templates you would make one partial specialization to break down the signature into its parts:

template<typename Signature>
class Test;
// or the SFINAE-friendlier
//template<typename Signature>
//class Test {};
// or the hard-error-friendlier
//template<typename Signature>
//class Test {
//    static_assert(Bool<false, Signature>{},
//                  "template argument must be a signature returning void");
// // Bool is from http://flamingdangerzone.com/cxx11/2012/05/29/type-traits-galore.html#dependent_boolean
//};

template<typename... Args>
class Test<void(Args...)>
{
    public:
        void operator()(Args...) const;
};

Without variadic templates you have to make one specialization for each number of arguments. Macros may be of help to generate all those (Boost.PP, or maybe those that Visual Studio uses to emulate variadic templates in the standard library).

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
10
template <class Ty>
class Test; /* not defined */
template <class Ret, class Arg0>
class Test<Ret(Arg0)> { /* whatever */ }
template <class Ret, class Arg0, class Arg1>
class Test<Ret(Arg0, Arg1)> { /* whatever */ }
template <class Ret, class Arg0, class Arg1, class Arg2>
class Test<Ret(Arg0, Arg1, Arg2)> { /* whatever */ }

Continue the tedious repetition until you have enough arguments for your needs. In TR1 it was recommended that the various function object templates be able to handle 10 arguments. This was typically implemented with fairly sophisticated macros to simplify coding, but it can be done by brute force.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165