I have some variadic template method, which looks like this:
template<typename ... Args>
void Invoke(const char* funcName, Args ... args) const;
template<typename ... Args>
void Invoke(const char* funcName, Args ... args) const
{
SPrimitive params[] = { args ... };
SomeOtherInvoke(funcName, params, sizeof ... (Args));
}
Here SPrimitive - just a simple struct with a constructor for any primitive type.
I want to make one more Invoke definition for some complex type. And here is my question: Is it possible to make variadic template method specialization in c++ 11/14 ? I mean something like this ( for simplicity lets my type will be int):
template<int ... Args>
void Invoke(const char* funcName, Args ... args)
{
int params[] = { args ... };
SomeComplexInvoke(funcName, params, sizeof ... (Args));
}
Here I want a specialization, which takes any parameters count of type int, so I can call it just like this:
Invoke("method", 2, 4 ,9);
As @Jarod42 mentioned, it should not be done with specialization. In your example you want something special if all argument types are int
, so let's write a template which will check it:
template<typename ref, typename t, typename ...types>
struct all_same {
static constexpr bool value = std::is_same<ref, t>::value && all_same<ref, types...>::value;
};
template<typename ref, typename t>
struct all_same<ref, t> {
static constexpr bool value = std::is_same<ref, t>::value;
};
It checks whether first type argument is equal to all other type arguments. Then in Invoke
we should select params
type based on args...
types:
template<typename ... Args>
void Invoke(const char* funcName, Args ... args)
{
using params_type = typename std::conditional<all_same<int, Args...>::value, int, SPrimitive>::type;
params_type params[] = { args ... };
SomeOtherInvoke(funcName, params, sizeof ... (Args));
}
Now for the sake of demonstration let's define:
struct SPrimitive{
};
void SomeOtherInvoke(const char*, SPrimitive*, size_t) {
std::cout << "Invoked for SPrimitive\n";
}
void SomeOtherInvoke(const char*, int*, size_t) {
std::cout << "Invoked for int\n";
}
and call
Invoke("foo", SPrimitive());
Invoke("foo", SPrimitive(), SPrimitive());
Invoke("foo", 1, 2, 3, 4);
The output is:
Invoked for SPrimitive
Invoked for SPrimitive
Invoked for int
which is what you asked for.
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