К сожалению, в двух местах, которые аргументы шаблона ARGS допускают разные типы для каждого вариационного расширения (и каждого отдельного аргумента).
Вам необходимо сделать аргументы (например, ARGS && ... args) зависимыми или статическими.Вы можете использовать утомительный метод, который, я считаю, сохраняет идеальную пересылку, который показан последним, потому что он довольно многословный.
Этот метод мой любимый, так как он очень хорошо работает с intelisense.В некоторых случаях этот метод не «совершенен вперед», но он почти всегда будет таким же, поэтому, может быть, он хорош для вас:):
#include <iostream>
using namespace std;
void func (int foo)
{
std::cout << foo << "\n";
}
template <typename T>
struct Mirror
{
using type = T;
};
template < typename ... FunctionArgs >
void proxy (void (*callback) (FunctionArgs ...), typename Mirror<FunctionArgs>::type ... args)
{
callback (args ...);
}
int main ()
{
proxy (func, 17);
int foo = 17;
proxy (func, foo);
}
Метод статического приведения:
#include <iostream>
using namespace std;
void func (int foo)
{
std::cout << foo << "\n";
}
template < typename ... FunctionArgs, typename ... UsedArgs >
void proxy (void (*callback) (FunctionArgs ...), UsedArgs && ... args)
{
callback (static_cast < FunctionArgs > (args) ...);
}
int main ()
{
proxy (func, 17);
int foo = 17;
proxy (func, foo);
}
Детальный метод, я думаю, что он сохраняет все идеальные пересылки:
#include <iostream>
using namespace std;
void func (int foo)
{
std::cout << foo << "\n";
}
template <typename T>
struct Mirror
{
using type = T;
};
template < typename ... FunctionArgs, typename ... UsedArgs >
void proxy (void (*callback) (FunctionArgs ...), UsedArgs && ... args)
{
callback ([](auto m, auto && a) -> decltype(auto)
{
if constexpr (std::is_reference_v<decltype(a)>)
{
return std::forward<decltype(a)>(a);
}
else
{
return static_cast<typename decltype(m)::type>(a);
}
}( Mirror<UsedArgs>{}, std::forward<FunctionArgs>(args) ) ... );
}
int main ()
{
proxy (func, 17);
int foo = 17;
proxy (func, foo);
}