【问题标题】:How can I apply the [[nodiscard]] attribute to a lambda?如何将 [[nodiscard]] 属性应用于 lambda?
【发布时间】:2017-04-28 18:05:25
【问题描述】:

我想防止人们在不处理返回值的情况下调用 lambda。

Clang 4.0 拒绝我尝试过的一切,使用 -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

这是 clang 中的某种错误还是标准中的漏洞?

【问题讨论】:

  • [expr.prim.lambda] 建议[&]() [[nodiscard]] { return 1; }
  • ...但是,[dcl.attr.nodiscard] 不允许在 lambda 中使用该特定属性。如果我不得不猜测,我会说这是因为它几乎没有用处:lambdas 通常作为回调传递给代码的其他部分,因此无论如何都无法检查 nodiscardiness。
  • 嗯,您编辑的问题似乎已经包含您在诊断过程中需要的确切答案:-S
  • 我经常将它们用作本地函数,在这种情况下,nodiscardiness 是相关的,除非我完全误解了 nodiscardiness。
  • 当然,但如果仅在本地使用,您可以查看是否调用它们。将 API 函数标记为 nodiscard 的价值在于,vector::empty 之类的东西不会被第三方误解。如果是你自己的代码,那问题就小得多了。

标签: c++ lambda attributes language-lawyer c++17


【解决方案1】:

can't apply nodiscard to lambdas,但是你可以写一个包装器:

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.

【讨论】:

  • 为像我这样的挑剔者添加const noexcept(noexcept(f(std::forward&lt;T&gt;(t)...)))operator() 怎么样? :)
  • @Rostislav 我不确定const 是一个严格的改进,因为它阻止我们在F 中使用非const operator()s,尽管这对于lambdas。
  • 是的,我的大脑完全依赖于 lambda 和他们的 operator(...) const。包装器中的 constnon-const 重载可能是正确的。但这一切肯定取决于用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 2021-05-18
  • 2012-04-07
  • 2021-11-13
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多