首页 > 解决方案 > 函数接受函数作为模板类型的参数

问题描述

我对编程和 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&& ... 参数)^

这是可行的,怎么做?非常感激。/约翰

标签: c++templates

解决方案


模板推导仅适用于您传入的确切类型,因此如果您传入函数指针,则模板无法推断出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
}

大多数情况下,您不需要推断回调的签名。只需使用您期望它采用的参数调用它。

如果这还不够,还有一些方法可以推断出回调的签名,但它会变得有点冗长,而且大多数时候没有真正的用途。


推荐阅读