一般可能是模板可变参数没写对
这里给个正确能编译运行的代码参考:
// 下面是一个使用std::future<Ret> 的完整使用案例
#include <iostream>
#include <future>
#include <chrono>
int add(int a, int b) // 定义求和函数
{
std::cout << "process add for 2 seconds..." << std::endl;
std::this_thread::sleep_for (std::chrono::seconds(2));
return a + b;
}
template <typename Ret, typename Func, typename ... Arg> // 定义泛型函数
Ret AsyncCallback(Func f, Arg ... arg)
{
std::packaged_task<Ret(Arg ...)> task(f); // 创建一个std::packaged_task对象
std::future<Ret> future = task.get_future(); // 获取函数的返回值
std::cout << "thread start" << std::endl;
std::thread t(std::move(task), arg ...); // 创建线程执行函数
//t.join(); // 等待线程结束 //必须显示join或detach子线程,否则后面future.get就会报错,不知道什么原因
t.detach();
//do something...
std::cout << "do something for 1 second..." << std::endl;
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << "future.get()..." << std::endl;
return future.get();
}
int main()
{
int result = AsyncCallback<int>(add, 5, 10); // 调用AsyncCallback函数
std::cout << "Result of add is: " << result << std::endl;
return 0;
}
编译运行结果:
20230816
文章目录
C++编译报错:couldn’t deduce template parameter ‘xxx’(模板参数推导失败)
一、引言
在C++编程中,模板是一个强大的工具,可以增加代码的可重用性和灵活性。然而,它们也可以带来一些复杂性,并有时可能导致难以理解的编译错误。本文将探讨“couldn’t deduce template parameter ‘xxx’”这个常见错误。
二、模板参数推导
在深入讨论这个问题之前,首先了解一下模板参数推导的概念。
2.1 模板参数推导基础
在调用函数模板时,编译器通常可以自动推导出模板参数的类型。例如:
template<typename T>
void foo(T param) { /* ... */ }
int main() {
int x = 0;
foo(x); // 编译器推导出T为int
}
在上述代码中,编译器能够成功推导出T
的类型为int
。
2.2 模板参数推导规则
但是,模板参数推导并不总是那么直观。它遵循一组特定的规则,这些规则定义了编译器如何处理各种情况1。例如,当参数是引用或指针,或者使用了const
或volatile
修饰符时,推导规则会有所不同。
三、错误原因与解决方法
3.1 错误原因
"couldn’t deduce template parameter ‘xxx’"的错误发生在编译器无法推断出模板参数的类型时。这通常是因为提供给函数的参数类型与函数模板声明不匹配,或者编译器无法从上下文中推断出参数的类型。
例如:
template<typename T>
void foo(T* param) { /* ... */ }
int main() {
int x = 0;
foo(x); // 错误:不能从int推断出T*
}
在这段代码中,foo
函数需要一个指向T
类型的指针,但是我们提供了一个int
。因此,编译器无法推断出T
的类型,导致出现了错误。
3.2 解决方法
要解决这个问题,需要确保调用函数时提供的参数类型与函数模板声明匹配。在上述例子中,应该传递一个指针,而不是一个整数:
int main() {
int x = 0;
foo(&x); // 正确:编译器可以从int*推断出T为int
}
如果函数模板过于复杂,使得编译器无法推断出所有参数的类型,那么可以考虑显式地提供模板参数:
foo<int>(&x); // 显式指定T为int
这样,就可以消除编译器的疑虑,并确保正确地实例化模板。
四、案例分析
下面是一些实际的编译错误示例,以及如何解决它们。
4.1 多参数模板函数
考虑以下多参数模板函数:
template<typename T, typename U>
void bar(T t, U u) { /* ... */ }
调用这个函数时,可能会遇到一些问题。例如:
bar(1, 2.0); // 错误:不能推导出T和U的类型
尽管1
明显是int
,2.0
明显是double
,但由于两者都可以转换为另一种类型(即,可以将int
升级为double
,也可以将double
降级为int
),所以编译器无法确定应该选择哪种类型。
解决这个问题的一种方法是显式地提供模板参数:
bar<int, double>(1, 2.0); // 显式指定T为int,U为double
4.2 函数返回值类型依赖于模板参数
如果函数的返回值类型依赖于模板参数,编译器可能无法推断出模板参数的类型。例如:
template<typename T>
T baz() { return T(); }
在这个例子中,如果我们试图这样调用baz
函数:
auto x = baz(); // 错误:不能推导出T的类型
编译器会报错,因为它无法确定T
的类型。解决这个问题的方法是显式地提供模板参数:
auto x = baz<int>(); // 显式指定T为int
五、总结
C++模板是一个强大的工具,但同时也带来了一些复杂性。正确理解和使用模板参数推导是避免错误的关键。当编译器报告“couldn’t deduce template parameter”的错误时,通常意味着我们需要更仔细地检查函数模板的声明和调用,以确保它们匹配,或者需要显式地提供模板参数。
ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ ᅟᅠ
https://en.cppreference.com/w/cpp/language/template_argument_deduction ↩︎