c++ - Template argument deduction fails on lambda using tuple -
i'm trying make query function lets me query stl container element characteristics, , return result set. it's syntactic sugar around normal stl operations (specifically, copy_if , back_inserter).
#include <string> #include <tuple> #include <functional> #include <vector> // query function, 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 row, each column having type using row = std::tuple<int, float, std::string>; int main() { // create sample vector of rows std::vector<row> vec; for(size_t = 0; < 100; ++i) vec.emplace_back(i, 5.0f, "hello"); // how perform query // **** line doesn't compile due template arg deduction failure **** auto result = query(vec, [](row const& row) -> bool { return true; }); return 0; }
and here compiler output (clang 3.3)
main.cpp:27:19: error: no matching function call '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.
a lambda not std::function
, class type overloaded operator()
, 2 distinct types. query
function requires std::function<...>
argument, , template argument deduction requires types exact matches (besides cv-qualifiers), conversion lambda expression std::function
never deduced.
one solution, of course, construct std::function
before calling query
auto result = query(vec, std::function<bool(row const&)>( [](row const&) { return true; }));
another option change function itself
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; }
now can called using original code.
Comments
Post a Comment