拥有 [[nodiscard]] 类型的理由是什么?

mut*_*oid 4 c++ attributes c++17

在哪些用例中使用[[nodiscard]]类型是有益的?

在类型上,[[nodiscard]]如果省略返回该类型实例的任何函数的返回值,则发出警告;(引自 p0068r0):

如果 [[nodiscard]] 被标记在一个类型上,它使得所有返回该类型的函数都隐式地 [[nodiscard]]。

[[nodiscard]]构造函数(c++2a)对于管理资源的类(例如unique_ptr)和函数的 nodiscard非常有用,例如因为make_unique我无法提出一个类型的 nodiscard 有用的示例,我对使用的场合。

Bri*_*ian 6

考虑类型std::unique_lock<M>。它是标记构造函数(特别是使用 的构造函数M&)nodiscard的明显候选者,因为我们不想意外地编写一些这样的代码:

std::unique_lock<M>(m);
// oops! we actually meant
// std::unique_lock<M> lck(m);
Run Code Online (Sandbox Code Playgroud)

这属于“管理资源”类别。

但这也是一个我们不希望从函数返回时丢弃的类型的示例:

std::unique_lock<M> getLockFor(Arg x) {
    std::unique_lock<M> result;
    // acquire some lock based on x
    return result;
}

{
    auto lck = getLockFor(arg1);  // ok
    // do some stuff that requires the lock to be held
}
{
    getLockFor(arg2);  // warning!
    // lock will NOT be held here!
}
Run Code Online (Sandbox Code Playgroud)

要在这种情况下获得警告,我们需要将类型标记为 nodiscard,而不仅仅是构造函数。

我认为,事实上,这个例子说明了也许大多数管理资源的类都应该被 nodiscard,因为当我们调用一个返回给我们对资源的控制权的函数时,它可能是一个错误,仅仅通过不使用返回值。