template<typename T>
void Test_FuncWrapper(const std::function<void(const T&)>& handle)
{
//! handle(value);
}
int main(int argc, char* argv[])
{
Test_FuncWrapper([](const int& a)->void{ std::cout << a << std::endl;});
return 0;
}
上述代码在编译的时候,总是报无法推导出T的类型,请问该如何解决这类问题???
错误信息如下:
/home/insights/insights.cpp:131:3: error: no matching function for call to 'Test_FuncWrapper'
131 | reg::Test_FuncWrapper([](const int& a)->void{ std::cout << a << std::endl;});
| ^~~~~~~~~~~~~~~~~~~~~
/home/insights/insights.cpp:70:8: note: candidate template ignored: could not match 'std::function<void (const T &)>' against '(lambda at /home/insights/insights.cpp:131:25)'
70 | void Test_FuncWrapper(const std::function<void(const T&)>& handle)
💡解答
问题分析:
std::function
是一种通用的可调用对象包装器。当使用std::function
作为模板参数时,编译器在进行模板参数推导时可能会遇到困难。在给定的代码中,Test_FuncWrapper
模板函数期望一个std::function<void(const T&)>
类型的参数,但传入的是一个lambda表达式。编译器无法直接从lambda表达式推导出T
的类型。解决方法:
显式指定模板参数:
Test_FuncWrapper
时显式指定模板参数T
的类型。修改后的代码如下:
使用自动推导的模板参数:
Test_FuncWrapper
函数,使其直接接受可调用对象,而不是std::function
包装的对象。这样编译器可以更好地进行模板参数推导。修改后的代码如下:
在C++17及以后:
auto
模板参数和std::invoke
来简化代码并解决类型推导问题。修改后的代码如下:
改进原
std::function
版本(C++17及以后):可以使用
std::type_identity
来辅助类型推导。虽然这种方法相对复杂,但对于保持原std::function
参数形式有帮助。通过上述方法,可以解决
std::function
在模板函数中类型推导失败的问题。不同的方法适用于不同的场景和C++标准版本,可根据实际需求选择。