Search code examples
c++staticconstantsgrammarnoexcept

A question about c++ grammar [static const auto compare = [](const std::string& now, const std::string& next) noexcept ->bool ]


static const auto compare = [](const std::string& now, const std::string& next) noexcept ->bool 
    {
        return now.size() == next.size() ? now < next : now.size() < next.size();
    };

I saw this code on Hacker rank and I do not understand how it works.

Q1. Why this guy used static const auto and const std::string Q2. What does [] mean ? Q3. Why string&? not string Q4. what does noexcept -> bool mean?

Any comments would be greatly appreciated!


Solution

  • I'm not sure if this should be answered or closed with a generic duplicate regarding lambda syntax, but there's so much going on here, I'm tempted to explain it step by step.

    First of all, I suggest getting a good book for learning C++ (particularly one covering C++11), rather than HackerRank or any other "competitive programming" website. Code written there can rarely be called "good" and solutions provided by others (as you noticed) are commonly just to flex their own knowledge, not to share it with others.

    What you see is a single lambda expression. It defines a lambda called compare, which takes two const std::string& as arguments and returns bool. It is likely used later in a function from <algorithm> library. Simplifying, lambda is a short syntax for a function, which can be called later on somewhere else.

    Lambda syntax is as follows:

    [ capture-list ] ( parameters ) optional-qualifiers -> return-type { body } 
    

    Your lambda has:

    • empty capture list (it operates only on the parameters provided each call)
    • two arguments of type const std::string&, which are passed with every call to lambda.
    • noexcept qualifier - programmer promises that no exceptions will be thrown by this lambda
    • return type bool
    • body of single line return now.size() == next.size() ? now < next : now.size() < next.size();

    Regarding variable compare, there are several keywords used to define it:

    • static strongly depends on context - it means something different in class scope and in namespace scope. Read more in this question
    • const is quite obvious - this variable will not change. Required to initialize static class members in place.
    • auto - let the compiler deduce type of variable. Lambdas don't have any common name for type, so auto or std::function<> are only options one can use.

    Finally:

    Q3. Why string&? not string

    Why not? There is absolutely no reason to copy arguments into lambda, so it's much faster to pass them by reference. More on that topic: What's the difference between passing by reference vs. passing by value?