I was playing with variadic template parameters using gcc 4.6.1. The following code compiles as expected:
template<typename RetType, typename... ArgTypes>
class Event;
template<typename RetType, typename... ArgTypes>
class Event<RetType(ArgTypes...)>
{
public:
typedef function<RetType(ArgTypes...)> CallbackType;
void emit(ArgTypes...args)
{
for (CallbackType callback : callbacks)
{
callback(args...);
}
}
private:
vector<CallbackType> callbacks;
};
But to my suprise the following "normal" version that has only one "Argument Type" doesn't compile:
template<typename RetType, typename ArgType>
class Event;
template<typename RetType, typename ArgType>
class Event<RetType(ArgType)> // <- error: wrong number of template arguments (1, should be 2)
{};
g++ 4.6.1 gives error as in the comment.
Anybody knows why it causes the error and how to make it work? Also, am I right in thinking the above code is a form of "template partial specialisation"?
Templates are powerful features of C++ which allows us to write generic programs. We can create a single function to work with different data types by using a template.
The use of templates can be thought of as compile-time polymorphism. The technique is used by a number of languages, the best-known being C++, but also Curl, D, Nim, and XL.
A template is a form, mold or pattern used as a guide to make something.
To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>( float original ); Template arguments may be omitted when the compiler can infer them.
If you want to make your own version of std::function
for fun, it should look like this:
template<class Signature>
class Event;
template<class R, class... Args>
class Event<R(Args...)>{
// ...
};
Why your first version works is already explained by @ronag, a parameter pack (...
in template parameter) means zero or more. The code I gave above is still the correct signature if you want a std::
/boost::function
-like class (int(int, double, char)
is a function type, that's why it can fit into a single type declaration like class Signature
).
template<typename RetType, typename ArgType>
class Event;
Expects 2 template arguments, RetType
and ArgType
, you only give it one RetType(ArgType)
.
template<typename RetType, typename... ArgType>
class Event;
Expects 1 or more template arguments, RetType
and optional ArgType
s.
I think that the error is due to the fact that if the template is not variadic, then the cpomiler expects the standard form, that is class Event<templateArg1, templateArg2>
, which is clearly not what you're feeding it with.
About the template specialization: I disagree, if I'm not wrong what you're doing there is to forward the declaration of the class Event
, then effectively declare it just 2 lines later.
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