2

I have the following function:

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

To this function, I am trying to pass a lambda function like this:

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

Where rng is Range of List of floats, so Range::ConstReference is defined as const float&

My compiler (gcc) complains about type mismatch

C:\Programming\Collections\main.cpp|24|note:   mismatched types 'bool (*)(typename Range::ConstReference)' and 'main(int, char**)::< lambda(const float&) >'|

Can anybody tell me what is wrong with my code?

Edit:

When I pass function like this, it works:

bool (*func)(const float& v) = [](const float& v) { return v < 0.0f; };

When I try to use auto keyword, it is same problem as before:

auto func = [](const float& v) { return v < 0.0f; };
6
  • 1
    You should be checking val, not v. Commented Sep 6, 2014 at 18:20
  • You already have an answer explaining what's wrong, but what might also be useful is a workaround: rng = FindFirstIf(rng, +[](const float& v) { return (v < 0.0f); });. The + forces the lambda to be converted to a function pointer directly (since the lambda class does not provide an overloaded + operator, but does provide a conversion-to-pointer operator to the result of which + can be applied), and GCC 4.8 doesn't detect that as a mismatched type. Commented Sep 7, 2014 at 2:32
  • @hwd thanks thats really nice workaround Commented Sep 8, 2014 at 11:22
  • @manlio I'm not sure why you felt it necessary to edit the tags here at all, but if you're going to do that, please make sure to use the right tags. The OP isn't using GCC 4.9. We can know that from the fact that the code isn't working for the OP. Commented Sep 11, 2014 at 10:09
  • @hvd From the accepted answer it seems to be a gcc bug resolved in v4.9 Commented Sep 11, 2014 at 10:10

1 Answer 1

2

I suspect that either you have a type-o in your code, or you are using a version of gcc that does not completely implement lambdas (or possibly both).

If your example was:

[](const float& val) { return (val < 0.0f); }

(v -> val)

and if Range::ConstReference is a const float&, then the code is legal C++11.

The tricky part here is that some lambdas will implicitly convert to a function pointer. That is, those lambdas with no lambda-capture will convert to a function pointer with an identical signature.

This:

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

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

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

compiles for me.

With a little poking around with online gcc compilers, this appears to be a bug in gcc 4.8, fixed in 4.9.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The val - v was just a typo so it looks like the problem is in my compiler version.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.