我正在尝试创建一个查询函数,让我查询某个元素特征的STL容器,然后返回结果集。它实际上只是普通STL操作的语法糖(特别是copy_if和back_inserter)。
#include <string>
#include <tuple>
#include <functional>
#include <vector>
// This is the query function, it compiles fine
template<typename T, typename ... U>
T query(T const& input, std::function<bool(std::tuple<U...> const& row)> pred)
{
T result;
std::copy_if(std::begin(input), std::end(input), std::back_inserter(result), pred);
return result;
}
// Define my Row, with each column having a type
using Row = std::tuple<int, float, std::string>;
int main()
{
// Create a sample vector of Rows
std::vector<Row> vec;
for(size_t i = 0; i < 100; ++i)
vec.emplace_back(i, 5.0f, "hello");
// This is how I would perform the query
// **** This is the line that doesn't compile due to template arg deduction failure ****
auto result = query(vec, [](Row const& row) -> bool { return true; });
return 0;
}
这是编译器输出(Clang 3.3)
main.cpp:27:19: error: no matching function for call to 'query'
auto result = query(vec, [](Row const& row) -> bool { return true; });
^~~~~
main.cpp:8:3: note: candidate template ignored: failed template argument deduction
T query(T const& input, std::function<bool(std::tuple<U...> const& row)> pred)
^
1 error generated.
答案 0 :(得分:2)
lambda不是std::function
,它是一个带有重载operator()
的类类型,两者是不同的类型。 query
函数需要std::function<...>
参数,模板参数推导要求类型完全匹配(除了cv-qualifiers),因此从lambda表达式到std::function
的转换永远不会推导出来
当然,一种解决方案是在调用std::function
query
auto result = query(vec,
std::function<bool(Row const&)>(
[](Row const&) { return true; }));
另一种选择是改变你自己的功能
template<typename T, typename UnaryPredicate>
T query(T const& input, UnaryPredicate&& pred)
{
T result;
std::copy_if(std::begin(input), std::end(input),
std::back_inserter(result), std::forward<UnaryPredicate>(pred));
return result;
}
现在可以使用原始代码调用它。