This code compiles with both gcc and clang:
#define PACK //...
template <typename Result, typename PACK Args, typename Last>
auto g(Result (*f)(Args PACK, Last)) -> Result (*)(Args PACK)
{
return reinterpret_cast<Result (*)(Args PACK)>(f);
}
double af(char c, int i);
auto ag{g(&af)};
However, if I change the first line to:
#define PACK ...
Neither compiler will accept it. The error says that template type argument detection failed. Why can an individual type be detected, but not as a (degenerate) pack?
(Some background: I'm working with an application that takes advantage of the fact that, using reinterpret cast, typical ABIs guarantee it's safe to assign a function address to a function pointer if the function's argument types are prefix of the argument types of the pointed to function type, and the return types match. I was trying to write a template that would statically check for this condition.)
The correct syntax for the second case to work would be as shown below. Note how the order of Last
and Args...
is changed.
//----------------------------------------------------vvvv--->OK: Last is deducible
template <typename Result, typename... Args, typename Last>
auto g(Result (*f)(Last, Args...)) -> Result (*)(Args...)
//-----------------------^^^^------------------------------>order changed here
{
return reinterpret_cast<Result (*)(Args...)>(f);
}
int func(int, float, double, char, bool);
auto ptr = g(&func);
Demo
//---------------------------------vvvv--------------------->Last comes before Args though this is not necessary here as it is deducible as shown in method 1 above
template <typename Result,typename Last, typename... Args>
auto g(Result (*f)(Last, Args...)) -> Result (*)(Args...)
//-----------------------^^^^------------------------------>order changed here
{
return reinterpret_cast<Result (*)(Args...)>(f);
}
int func(int, float, double, char, bool);
auto ptr = g(&func);
Demo
As 康桓瑋 noted in a comment on the question, parameter packs are only permitted at the end of a function's formal parameter list.
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