i传递给构造函数时,为什么以下内容无法编译。编译其他类似的构造。

#include <iostream>
#include <functional>

int RetXPrintU(int x, uint u)
{
    std::cout << "RetXprintU(): " << u << std::endl;
    return x;
}

template <typename Fn, typename... Args>
void Call(Fn&& fun, Args&&... args)
{
    std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}

template <typename Fn, typename... Args>
class CallableObj
{
public:
    explicit CallableObj(Fn&& fun, Args&&... args)
    {
        std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
    }
};

int main() {
    int i = 4;
    std::invoke(RetXPrintU, i, 8u);
    Call(RetXPrintU, i, 8u);
    CallableObj co(RetXPrintU, i, 8u); // WHY I DO NOT COMPILE?
    //CallableObj co(RetXPrintU, 0, 8u); // WHY I COMPILE?

    return 0;
}

最佳答案

如错误消息所述,编译器无法推断CallableObj的模板参数。您需要为此添加一个推导指南:

template <typename Fn, typename... Args>
CallableObj(Fn&& fun, Args&&... args) -> CallableObj<Fn, Args>...>;

整个代码为:
template <typename Fn, typename... Args>
class CallableObj
{
public:
    explicit CallableObj(Fn fun, Args... args)
    {
        std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
    }
};

template <typename Fn, typename... Args>
CallableObj(Fn&& fun, Args&&... args) -> CallableObj<Fn, Args...>;

正如@ Jarod42指出的那样,无需将构造函数本身作为模板(就像在答案的第一个版本中一样)。

这是live example(@ Jarod42的更正版本)。

我以为您的代码只是一个最小的示例,您需要将该类作为模板。如果不是这种情况,则最好选择其他解决方案。

09-30 11:31