c++ - 函数接受函数作为模板类型的参数
问题描述
我对编程和 C++ 相当陌生。我有一个函数,我想接受带有模板值的函数指针作为参数。这就是我的意思...
我有这个功能:
template<typename... ColumnTypes, typename... ParameterTypes>
void query(std::function<void(bool success, ozo::rows_of<ColumnTypes...>& results)> callback, const
std::string& query, ParameterTypes&& ... parameters);
“ozo::rows_of”是以下的别名:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
我希望每个查询都提供一个回调,这个回调需要能够接受不同的类型。例如。“列类型”
我试过的:
void myfunc(bool succeeded, ozo::rows_of<int>& results)
{
//code
}
postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
结果:
.cpp:241:26: error: no matching member function for call to 'query'
postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
~~~~~~~~~~~~~~~~~^~~~~
.h:165:22:注意:候选模板被忽略:无法匹配 'function<void (bool, vector<tuple<type-parameter-0-0...>, allocator<tuple<type-parameter-0-0 ...> > > &)>' 针对 'void (*)(bool, std::vectorstd::tuple<int, std::allocatorstd::tuple<int > > &)' void PostgresCaller::query(std ::function<void(bool success, ozo::rows_of<ColumnTypes...>& results)> 回调, const std::string& 查询, ParameterTypes&& ... 参数)
我也尝试过使用 lambda:
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
{
//code
}, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
结果:
error: no matching member function for call to 'query'
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
~~~~~~~~~~~~~~~~~^~~~~
.h:165:22:注意:候选模板被忽略:无法匹配 'function<void (bool, vector<tuple<type-parameter-0-0...>, allocator<tuple<type-parameter-0-0 ...> > > &)>' 针对 '(lambda at .cpp:241:32)' void PostgresCaller::query(std::function<void(bool success, ozo::rows_of<ColumnTypes...>&结果)> 回调,常量 std::string& 查询,ParameterTypes&& ... 参数)^
这是可行的,怎么做?非常感激。/约翰
解决方案
模板推导仅适用于您传入的确切类型,因此如果您传入函数指针,则模板无法推断出std::function
将该函数指针转换为哪种类型。
使 callable 成为模板参数,而不是使用std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
callback( ... ); // use it like this
}
大多数情况下,您不需要推断回调的签名。只需使用您期望它采用的参数调用它。
如果这还不够,还有一些方法可以推断出回调的签名,但它会变得有点冗长,而且大多数时候没有真正的用途。
推荐阅读
- node.js - 无法在本地通过nodejs数据库连接到PostgreSQL它突然停止在mac上工作
- node.js - 如何在 Firebase 函数中使用 CircleCI 环境变量
- django - Django UUIDField 文档说可以序列化,但迁移将其标记为“serialize=False”
- mysql - 在 Xampp 上安装 Dreamfactory
- reactjs - 尝试朗姆酒 npm start 命令时出错
- python - 如何将嵌套数组中的每个数组转换为数据框中的行?
- mysql - Mysql通过读取txt文件更新表?
- git - 无法通过命令行将我的 Web 应用程序推送到 GitHub 存储库
- time-complexity - 不同参数顺序操作的时间复杂度
- apache-spark - Hadoop:火花作业无法处理小数据集