Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 318
Dan Olson Avatar asked Apr 28 '17 18:04

Dan Olson


People also ask

What is[[ nodiscard]] in c++?

The [[nodiscard]] attribute can be used to indicate that the return value of a function shouldn't be ignored when you do a function call. If the return value is ignored, the compiler should give a warning on this.

Should I use Nodiscard?

Yes, using [[nodiscard]] is a good practice when discarding the result is likely a bug. That is the case quite often.

What are attributes in C++?

Attributes are modern ways in C++ to standardize things if their code runs on different compilers. Attributes are used to provide some extra information that is used to enforce conditions (constraints), optimization and do specific code generation if required.


1 Answers

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.

like image 72
Columbo Avatar answered Oct 07 '22 20:10

Columbo