gpt4 book ai didi

c++ - "template argument deduction/substitution failed"带有参数包的函数对象错误

转载 作者:行者123 更新时间:2023-11-30 03:16:46 28 4
gpt4 key购买 nike

我正在尝试创建一个函数,该函数接受任何类型的可变数量的参数,但即使是我制作的简单示例也会出现错误

#include <iostream>
#include <functional>

template<class... Ts>
void callFunction(const std::function<void(Ts...)>& function, Ts... parameters)
{
function(parameters...);
}

void myFunc(const std::string& output)
{
std::cout << output << std::endl;
}

int main()
{
callFunction<const std::string&>(&myFunc, "Hello world");
return 0;
}

当我在 Ideone 中运行上面的代码时,我得到这个错误:

prog.cpp: In function ‘int main()’:
prog.cpp:17:57: error: no matching function for call to ‘callFunction(void (*)(const string&), const char [12])’
callFunction<const std::string&>(&myFunc, "Hello world");
^
prog.cpp:5:6: note: candidate: template<class ... Ts> void callFunction(const std::function<void(Ts ...)>&, Ts ...)
void callFunction(const std::function<void(Ts...)>& function, Ts... parameters)
^~~~~~~~~~~~
prog.cpp:5:6: note: template argument deduction/substitution failed:
prog.cpp:17:57: note: mismatched types ‘const std::function<void(Ts ...)>’ and ‘void (*)(const string&) {aka void (*)(const std::__cxx11::basic_string<char>&)}’
callFunction<const std::string&>(&myFunc, "Hello world");

最佳答案

一个简单的建议:将可调用对象作为推导的类型名接收,而不是作为 std::function

我的意思是(还添加完美转发)

template <typename F, typename ... Ts>
void callFunction(F const & func, Ts && ... pars)
{ func(std::forward<Ts>(pars)...); }

而且,显然,不加解释地调用它

callFunction(&myFunc, "Hello world");

这是避免将可调用对象转换为 std::function 的额外优势。

无论如何,我在您的代码中发现了两个问题:

1) 如果您接收函数作为 std::function 接收参数类型列表(在本例中为可变参数列表,但对于此问题并不重要)作为列表相同类型的参数,您必须确定两个列表中的类型完全匹配。

这不是你的情况,因为该函数接收一个 std::string const & 并且你将字符串文字 "Hello world" 作为参数传递char const [12] 是不同的类型。

当要推导类型时,这会导致编译错误,因为编译器无法在两种类型之间进行选择。

您可以解决接收两个类型列表

template <typename ... Ts1, typename Ts2>
void callFunction (std::function<void(Ts1...)> const & function,
Ts2 && ... parameters)
{ function(std::forward<Ts2>(parameters)...); }

但是现在我们遇到了第二个问题

2) 您传递一个指针函数 (&myFunc),其中 callFunction() 等待 std::function

我们遇到了先有鸡还是先有蛋的问题,因为 &myFunc 可以转换为 std::function 但不是 std::function.

因此编译器无法从 &myFunc 中推断出 Ts... 类型列表,因为它不是 std::function并且无法将 &myFunc 转换为 std::function 因为不知道 Ts... 类型列表。

我看到您已经在 Ts... 列表中解释了 first 类型,但这还不够,因为 Ts... 列表是可变的,因此编译器不知道 Ts... 列表中只有一种类型。

此问题的一个简单解决方案是将函数作为简单推导的 F 类型传递。

否则,如果您使用两个模板类型列表编写了 callFunction(),则可以将 std::function 传递给函数

std::function<void(std::string const &)>  f{&myFunc};

callFunction(f, "Hello world");

但我认为这不是一个令人满意的解决方案。

关于c++ - "template argument deduction/substitution failed"带有参数包的函数对象错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55992377/

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