c++lambdaattributeslanguage-lawyerc++17

How can I apply the [[nodiscard]] attribute to a lambda?


I want to prevent people from calling the lambda without handling the return value.

Clang 4.0 refuses everything I've tried, compiling with -std=c++1z:

auto x = [&] [[nodiscard]] () { return 1; };
// error: nodiscard attribute cannot be applied to types
auto x = [[nodiscard]] [&]() { return 1; };
// error: expected variable name or 'this' in lambda capture list
auto x [[nodiscard]] = [&]() { return 1; };
// warning: nodiscard attribute only applies to functions, methods, enums, and classes
[[nodiscard]] auto x = [&]() { return 1; };
// warning: nodiscard attribute only applies to functions, methods, enums, and classes
auto x = [&]() [[nodiscard]] { return 1; };
// error: nodiscard attribute cannot be applied to types

Is this some sort of bug in clang or a hole in the standard?


Solution

  • Update: C++23 introduced attributes on lambdas immediately following the captures, so your example syntax 1 is now correct!

    auto lambda = [] [[nodiscard]] (auto... params) {
        // ....
    };
    

    In C++20 or earlier, you can't apply nodiscard to lambdas, but you can write a wrapper:

    template <typename F>
    struct NoDiscard {
        F f;
        NoDiscard(F const& f) : f(f) {}
        template <typename... T>
        [[nodiscard]] constexpr auto operator()(T&&... t) const
          noexcept(noexcept(f(std::forward<T>(t)...))) {
            return f(std::forward<T>(t)...);
        }
    };
    
    int main() {
        NoDiscard([](int i) {return i;})(0);
    }
    

    Demo.