为什么模板参数推导因std :: function回调的可变参数模板参数而失败?

法雷诺

让我们考虑以下功能:

// run_cb_1(): Explicitly defined prototype
void run_cb_1(const std::function<void(int)> & callback, int p)
{
    callback(p);
}

// run_cb_2(): One template parameter
template <typename T>
void run_cb_2(const std::function<void(T)> & callback, const T & t)
{
    callback(t);
}

// run_cb_3(): Variable number of template parameters
template <typename ... Args>
void run_cb_3(const std::function<void(Args...)> & callback, const Args & ... args)
{
    callback(args...);
}

现在,如果我想按以下方式使用这些功能:

int main()
{
    auto f = [](int a){
        std::cout << a << '\n';
    };

    run_cb_1(f, 5);      // OK

    run_cb_2(f, 5);      // KO --> I understand why
    run_cb_2<int>(f, 5); // OK

    run_cb_3(f, 5);      // KO --> I understand why
    run_cb_3<int>(f, 5); // KO --> I don't understand why...

    return 0;
}

我得到一个“没有匹配的函数调用”run_cb_2()run_cb_3()而它完全罚款run_cb_1()

我认为它的行为符合预期,因为我没有提供template参数的类型(因为它不能像那样简单地推论得出run_cb_1())。

但是指定模板类型可以解决问题run_cb_2()(正如我期望的那样),但不能解决run_cb_3()


我知道我可以解决这个问题无论是通过显式声明f如下:

std::function<void(int)> f = [](int a){
    std::cout << a << '\n';
};

通过将f传递为:

run_cb_2(std::function<void(int)>(f), 5);
run_cb_3(std::function<void(int)>(f), 5);

我的问题是:为什么run_cb_3()即使显式指定模板类型,模板参数推导也会失败(带有可变模板参数)?

很明显,我错过了一些东西(也许是基本的东西),但我不知道它是什么。
任何帮助将不胜感激。

内森·奥利弗

失败的原因是因为编译器不能只使用一种类型。当你做

run_cb_2<int>(f, 5);

编译器查看run_cb_2并发现只有一个模板参数。既然您已经提供了它跳过演绎阶段并淘汰的方法run_cb_2<int>

run_cb_3<int>(f, 5);

您在另一艘船上。run_cb_3具有可变参数模板参数,这意味着仅提供int不足以跳过推论。您指定了第一个参数,但可能还有更多,因此它进入了参数推导阶段以求出答案。这意味着它将进行检查callback以确保其推导的内容与其推导的内容相匹配args由于lambda不是a std::function,因此无法Args...从中推导出来。一旦发生这种情况,编译器将停止并发出错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++可变参数模板推导失败

std :: function的可变参数模板参数

为什么可变参数模板参数推导对此函数指针失败?

推导可变参数模板函数的参数失败

可变参数模板参数包推导失败

为什么模板参数推导失败?

可变参数模板函数重载失败

可变参数模板对

可变参数模板作为std :: function的参数

std :: function中的可变参数模板参数匹配

使用std :: function作为参数的可变参数模板

可变参数模板类型推导

当参数包含std :: function ...时,C ++模板参数推导失败,并显示错误“候选模板被忽略” ...为什么?

为什么可变参数模板参数的这种替换失败?(在固定参数之前打包)

`std :: function`模板参数推导/替换失败

带有两个模板参数的可变参数模板推导失败

用`std :: function`和先前推导出的模板参数替换失败-为什么?

用默认参数推导可变参数模板参数

函数指针参数的可变参数模板参数推导

模板推导因已知参数而失败

为什么在std :: tuple和模板派生类中模板参数推导/替换失败?

std :: function模板参数推导

为什么这个嵌套的可变参数模板是无效的参数?

С++可变参数模板:实现可变参数

可变参数模板函数参数和引用类型推导

std :: function到可变参数成员函数,然后绑定可变参数模板参数

可变参数模板,类型扣除和std :: function

如何使用可变参数模板使用std :: function

可变参数模板类的可变参数模板