I have the following function declarations
template<typename RET, typename... PARAMS>
RET Execute(PARAMS... params)
{ ... }
template<typename RET>
RET Execute()
{ ... }
template<typename... PARAMS>
void Execute(PARAMS... params)
{ ... }
void Execute();
These calls work fine in both GCC and MSVC
Execute<int32_t>(static_cast<int8_t>(0), static_cast<int32_t>(0))
Execute<int32_t>()
Execute(static_cast<uint8_t>(0))
Execute()
This call works fine in GCC, but not in MSVC. I get an error for an ambiguous call to overload function. Just because the return type is the same as the first parameter.
Execute<int32_t>(static_cast<int32_t>(0), static_cast<int32_t>(0))
Considering it is not possible to explicitly give the typenames of the parameter pack, it is not ambiguous. Why does MSVC seem to have this wrong? Is there anyway to fix this?
This call works fine in GCC, but not in MSVC.
In my Debian stable, I get the same error also with clang++ 11.0.1-2 ("error: call to 'Execute' is ambiguous") and g++ 10.2.1 (" error: call of overloaded ‘Execute<int32_t>(int32_t, int32_t)’ is ambiguous").
Considering it is not possible to explicitly give the typenames of the parameter pack
Not exactly: you can explicit the typenames of the arguments or the types of the first arguments; this permit to overrides the typenames deduction from the arguments.
Why does MSVC seem to have this wrong?
My question is: why your g++ seems to have this right?
Is there anyway to fix this?
Yes, a very simple way: add a variadic list of non-types template parameter before the variadic list of the argument types.
I mean, write the third Execute()
as follows
template <int..., typename... PARAMS>
void Execute (PARAMS... params)
{ /* ... */ }
and maybe also the first one as follows
template <typename RET, int..., typename... PARAMS>
RET Execute (PARAMS... params)
{ /* ... */ }
This way you impose the PARAMS
types deduction from the params
and a explicit template parameter is necessarily the return type (when you can express it).