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.
If there is just a single template parameter, I name it T (or U,V for nested templates). When there are multiple parameters and the use is not immediately obvious then I use descriptive names prefixed with T. For example, TKey, TValue, TIdentifiier, etc ...
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
A function's signature includes the function's name and the number, order and type of its formal parameters. Two overloaded functions must not have the same signature. The return value is not part of a function's signature.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With