'Nothing is fixing the error "No match for function call" C++
I can't fix this error for the life of me.
I'm trying to measure the time it takes to run a function (which counts prime numbers in a vector, but that's beside the point) sequentially, then in parallel. There are other header files, but I included only the code relevant to the error.
Error:
prog.cpp:32:22: error: no matching function for call to ‘results_benchmark(int,
do_work<const __pstl::execution::v1::sequenced_policy, std::vector<unsigned int>*>::
<lambda(int, int)>)’
More details on the error:
In file included from prog.cpp:8:
benchmark.hpp:95:16: note: candidate: ‘template<class Op, class ... Args> constexpr
benchmark_results<typename std::invoke_result<_Functor, _ArgTypes>::type>
results_benchmark(const size_t&, Op&&, Args&& ...)’
95 | constexpr auto results_benchmark(
| ^~~~~~~~~~~~~~~~~
benchmark.hpp:95:16: note: template argument deduction/substitution failed:
benchmark.hpp: In substitution of ‘template<class Op, class ... Args> constexpr
benchmark_results<typename std::invoke_result<_Functor, _ArgTypes>::type>
results_benchmark(const size_t&, Op&&, Args&& ...) [with Op = do_work<const
__pstl::execution::v1::sequenced_policy, std::vector<unsigned int>*>::<lambda(int, int)>;
Args = {}]’:
prog.cpp:32:22: required from ‘auto do_work(ExecPolicy&, const Container&) [with
ExecPolicy = const __pstl::execution::v1::sequenced_policy; Container = std::vector<unsigned
int>*]’
test_a07.cpp:107:46: required from here
benchmark.hpp:95:16: error: no type named ‘type’ in ‘struct std::invoke_result<do_work<const
__pstl::execution::v1::sequenced_policy, std::vector<unsigned int>*>::<lambda(int, int)> >’
This is how I defined the function in question. It takes an int (number of times to run the lambda function) and a lambda.
The lambda accepts by reference an execution policy and a vector. It has only one line: a return statement calling count_if(), to which I pass the exec policy, begin(v) and end(v), and the function used to determine whether a number is prime.
template <typename ExecPolicy, typename Container>
auto do_work(ExecPolicy& ep, Container const& v)
{
auto return_from_results_benchmark =
results_benchmark(3,
[&](auto ep, auto v){
return count_if(ep, begin(v), end(v), is_prime_trial_division);
}
);
// some print statements...
return return_from_results_benchmark;
}
The function used to determine whether a number is prime: (tested, it works, can't change)
constexpr bool is_prime_trial_division(unsigned const& n)
{
using std::sqrt;
if (n < 2)
return false;
auto const sqrt_n = isqrt(n);
bool retval = true;
for (unsigned i=2; i <= sqrt_n && retval; ++i)
retval &= (n % i != 0);
return retval;
}
The definition of results_benchmark(): (in header file, can't change)
// benchmark_results
// This function will call op(args...) num_iters times returning the results
// as a benchmark_results structure...
//
template <typename Op, typename... Args>
constexpr auto results_benchmark(
std::size_t const& num_iters, Op&& op, Args&&... args
) ->
benchmark_results< std::invoke_result_t<Op, Args...> >
{
using namespace std;
using namespace std::chrono;
benchmark_results< std::invoke_result_t<Op, Args...> > retval;
for (size_t i{}; i != num_iters; ++i)
{
do_not_optimize_barrier();
auto time0 = steady_clock::now();
do_not_optimize_barrier();
if constexpr(!is_void_v<decltype(op(args...))>)
retval.results.push_back(op(args...));
else
op(args...);
do_not_optimize_barrier();
auto time1 = steady_clock::now();
do_not_optimize_barrier();
retval.time += duration<double>(time1-time0).count();
}
return retval;
}
In main, I call do_work():
auto s = do_work(std::execution::seq, &v);
If I don't call do_work(), prog.cpp compiles. I compile with the following options enabled:
g++ -std=c++20 -Wall -Wextra -Wold-style-cast -Werror -pthread -o prog.exe prog.cpp -ltbb
My questions:
- The main issue is the
no matching function for call.... Why does my function call not work?
How do I fix it without changing this:
template <typename ExecPolicy, typename Container>
auto do_work(ExecPolicy& ep, Container const& v)
- I don't need to use the parameters passed to do_work anywhere else, only to pass them to the lambda function. But when compiling, there's a warning(error)
unused parameterfor both. How do I fix this without changing the structure of do_work?
I've tried the following (...and probably more):
- changing the do_work() call
auto s = do_work(std::execution::seq, &v); //or
auto s = do_work(std::execution::seq, *v); //or
auto s = do_work(std::execution::seq, v); //or
auto sq = std::execution::seq;
auto s = do_work(sq, &v);
const auto sq = std::execution::seq;
auto s = do_work(&sq, &v);
- changing the lambda's parameters
[&](ExecPolicy ep, Container v){...}
[](ExecPolicy& ep, Container& v){...}
[&](auto& ep, auto& v){...}
[&](auto ep, auto v){...}
- changing the call to count_if
count_if(ep, std::begin(v), std::end(v), is_prime_trial_division);
count_if(ep, std::begin(v), std::end(v), is_prime_trial_division());
count_if(ep, std::begin(v), std::end(v), is_prime_trial_division(7));
Solution 1:[1]
The function signature of results_benchmark is
template <typename Op, typename... Args>
constexpr auto results_benchmark(
std::size_t const& num_iters, Op&& op, Args&&... args
) -> benchmark_results<std::invoke_result_t<Op, Args...>>
when you invoke it in the do_work function body
results_benchmark(3,
[&](auto ep, auto v){
return count_if(ep, begin(v), end(v), is_prime_trial_division);
}
);
The value of num_iters is 3, Op is deduced as a lambda type that accepts two arguments, and Args... is empty pack.
Since you specify the return type of results_benchmark as benchmark_results<std::invoke_result_t<Op, Args...>>, this will make invoke_result unable to deduce the return type of Op because Args... is the empty pack and Op expects to take two arguments.
Try this
results_benchmark(3,
[&] {
return std::count_if(ep, begin(v), end(v), is_prime_trial_division);
}
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
