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.)
CodePudding user response:
The correct syntax for the second case to work would be as shown below. Note how the order of Last
and Args...
is changed.
Method 1
//----------------------------------------------------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);
Method 2
//---------------------------------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);
CodePudding user response:
As 康桓瑋 noted in a comment on the question, parameter packs are only permitted at the end of a function's formal parameter list.