Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why this code have C2784 "could not deduce template argument" error

From Lambda function passed as parameter I can compile the example:

template <class Range>
Range FindFirstIf(Range, bool(*Function)(typename Range::ConstReference value));

struct range {  using ConstReference = const float&; };

range rng;
rng = FindFirstIf(rng, [](const float& val) { return (val < 0.0f); });

Of course it can't link as FindFirstIf is not implemented.

However, when I did a similar thing:

template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value));

std::vector <int> vi;
double d = 0;
vi =       MyTest(vi, d, [](double val) { return (val < 0.0f); });

It has compilation error:

error C2784: 'Range MyTest(Range,ValueType,bool (__cdecl *)(ValueType))' : could not deduce template argument for 'bool (__cdecl *)(ValueType)' from 'main::'

why so? I thought by passing d in, ValueType can be deduced as double?

like image 370
athos Avatar asked Oct 30 '22 18:10

athos


1 Answers

Use this instead (note the +):

vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });

Lambda functions can decay to function pointers in some cases, but they are not function pointers for themselves.
In other terms, deduction fails because it expects to work on a function pointer, but the lambda is not a function pointer, it could be converted of course, but first of all deduction must take place, but it cannot for the lambda is not the expected type, it could decay to it ... And so on.
By adding the + in front of the lambda, you force the conversion before it is passed to the function, thus MyTest receives an actual function pointer as expected and deduction goes on.

Here is a minimal, working example based on your code:

#include<vector>

template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value)) {}

int main() {
    std::vector <int> vi;
    double d = 0;
    vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });
}
like image 58
skypjack Avatar answered Nov 10 '22 20:11

skypjack