Проблема здесь в том, что вам нужно переместить шаблон из класса в конструктор. Если у вас
template <typename Fn, typename... Args>
class CallableObj
{
public:
explicit CallableObj(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};
Args&&...
не является ссылкой переадресации c, потому что она выводится для самого класса, а когда вы вызываете CallableObj co(RetXPrintU, i, 8u);
, создается экземпляр класса, и конструктор выделяется как
explicit CallableObj(int(int, unsigned int)&& fun, int&& arg1, unsigned int&& arg2)
То, что мы хотим, это
class CallableObj
{
public:
template <typename Fn, typename... Args>
explicit CallableObj(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};
, так что теперь Args
будет выводиться при вызове конструктора, а Args&&
теперь является ссылкой для пересылки.
Причина, по которой CallableObj co(RetXPrintU, 0, 8u);
работал в вашем примере, заключается в том, что 0
является prvalue, и prvalue может связываться со ссылкой на rvalue.