24

I want to find point, which has the less Y coordinate (if more of such points, find the one with smallest X). When writing it with lambda:

    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        if (p1.first->y() < p2.first->y())
            return true;
        else if (p1.first->y() > p2.first->y())
            return false;
        else 
            return p1.first->x() < p2.first->x();
    }

I am getting:

error C3499: a lambda that has been specified to have a void return type cannot return a value

what is the difference between:

    // works
    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        return p1.first->y() < p2.first->y();
    }

and

    // does not work
    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        if (p1.first->y() < p2.first->y())
            return true;
        else 
            return false;
    }
3
  • 2
    The construct if(expression) return true; else return false; is fundamentally ugly. Twice as ugly if the expression is really boolean. Commented Oct 25, 2011 at 12:45
  • 4
    @MichaelKrelin-hacker: True, but that is not why the compiler rejects the last example. Commented Oct 25, 2011 at 15:50
  • 4
    MSalters, sure, that's why comment and not answer. This is the answer to the question "what is the difference". And this is the major difference ;) Commented Oct 25, 2011 at 20:51

2 Answers 2

17

As Mike noted, if the lambda's body is a single return statement, then the return type is inferred from that (see 5.1.2/4) (thanks Mike).

std::min_element(begin, end, [] (const PointAndAngle & p1, const PointAndAngle & p2)
  -> bool 
 {
    if (p1.first->y() < p2.first->y())
         return true;
    else 
        return false;
}

Note -> bool.

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

9 Comments

And probably also good to take the arguments by const-reference, as the algorithm may well want to give you that.
thank you! shouldn't the -> bool be after () instead of [] ?
I guess it is because in the simple one-line form the cmpiler can easily deduce the return type, which he may not be able to once you introduce a conditional. Though you're right in that it is always a good idea to be explicit about the return type.
Two mistakes here: bool is in the wrong place, as relaxxx said; and the second line has return instead of if.
@TonyK: thanks for the hint. I don't now how I copy/hasted that :)
|
15

The return type of lambdas can be implicitly inferred, but you need to have a single return statement to achieve this; that's why your "working" lambda works (return type inferred to be bool).

sehe's solution explicitly declares the return type, so it works fine as well.

Update:

The C++11 standard, §5.1.2/4 states:

If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:

  • If the compound-statement is of the form { return expression ; } the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);

  • otherwise, void.

Your not-working lambda falls into the second category.

4 Comments

Interestingly, wikipedia also includes if all locations that return a value return the same type when the return expression is passed through decltype. in the set of lambdas that may omit the return type. But it looks like, according to the standard, this isn't the case.
@mackenir: Actually before digging into the standard I thought that it might be a compiler limitation as well (the original answer is phrased like that, but the edits were very soon after posting so didn't get logged). Wikipedia is definitely technically incorrect there.
BTW did you buy a copy of the C++11 standard? I can't find it for free download.
@mackenir: You can download N3242 from here. It's not the official standard (just a working copy from February) but the differences should be really minor.

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.