Suppose I have a class
enum CallbackType
{
SYNC,
ASYNC
}
template<CallbackType CB = SYNC, typename... Args>
class Callback
{
}
I would like to be able to optionally specificy the callback type while still being ablet to have variadic template argument. Now I understand that the compiler can't tell them apart, but maybe there is some way to handle the specific case where the first template argument is of CallbackType ?
Callback<int int> //Should be Callback<SYNC, int, int>
Callback<ASYNC, int, int> //Should be Callback<ASYNC, int, int>
There are two aspects of C++, when it comes to variadic templates, that are in conflict with each other in your case:
Defaulted template parameters should not precede non-defaulted template parameters.
Variadic template parameters should not precede non-variadic template parameters.
It is certainly possible, in many situations, to correctly declare, and use, templates whose parameters don't follow these rules, but those situations are not important for the purpose of this question. In your case, what it comes down to is that both of your template parameters want to be the last parameter in their template, for their own individual reasons. That's the problem, in a nutshell.
The easiest way to resolve this conflict is to use an inner template:
template<CallbackType CB = ASYNC>
class CallbackClass {
public:
template<typename... Args> class Callback
{
}
};
Then, your two examples become:
CallbackClass<>::Callback<int, int>
and
CallbackClass<ASYNC>::Callback<int, int>
You'll end up with longer class names, of course. But that's what typedef
and using
is for. For example:
template<typename ...Args>
using DefaultCallback=CallbackClass<>::Callback<Args...>;
then use
DefaultCallback<int, int>
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