gpt4 book ai didi

c++ - 为什么使用 std::function 回调的可变模板参数推导模板参数失败?

转载 作者:行者123 更新时间:2023-11-30 04:43:13 24 4
gpt4 key购买 nike

让我们考虑以下函数:

// 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().

我认为它的行为符合预期,因为我没有提供模板参数的类型(因为它不能像 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 不是 std::function它无法推断Args...从中。一旦发生这种情况,编译器就会停止并发出错误。

关于c++ - 为什么使用 std::function 回调的可变模板参数推导模板参数失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58398009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com