Última actualización:2026-10-12
C++17: el atributo [[nodiscard]]¶
Desde que C++17 introdujo el atributo [[nodiscard]], al escribir API disponemos de una herramienta más potente para marcar los valores de retorno de funciones que no deberían ignorarse al llamarlas. En este artículo exploraremos en profundidad el uso de [[nodiscard]] y prestaremos atención a algunas trampas potenciales.
¿Qué es [[nodiscard]]?¶
[[nodiscard]] es un atributo de función que indica al compilador que el valor de retorno de la función no debería ignorarse. Resulta especialmente útil en funciones de las que depende un valor de retorno, como las funciones predicado o las funciones fábrica.
¿Cómo usar [[nodiscard]]?¶
Es posible usar [[nodiscard]] en clases, constructores y enumeraciones. Aquí tienes algunos ejemplos:
class [[nodiscard]] A {};
class B {
public:
[[nodiscard]] B() = default;
};
enum class [[nodiscard]] State {
Default,
Foo,
Bar
};
En los ejemplos anteriores, el compilador emitirá una advertencia cuando el valor de retorno se ignore, lo que nos ayuda a detectar a tiempo bugs potenciales.
Atención: las trampas de [[nodiscard]]¶
Aunque [[nodiscard]] puede evitar eficazmente que los valores de retorno se ignoren sin querer, debemos vigilar algunas trampas potenciales. Una trampa habitual es que una función marcada con [[nodiscard]] devuelva un objeto similar a un guardián de ámbito (scope guard), para ejecutar la limpieza al final del ámbito (por ejemplo, confirmar una transacción).
[[nodiscard]] ScopeGuard createScopeGuard() {
// Implementation of a scope guard
}
// 在这里,用户可以选择忽略返回值,导致作用域立即销毁,从而失去清理效果
std::ignore = createScopeGuard();
Aunque [[nodiscard]] indica que el valor de retorno de la función no debería ignorarse, el usuario todavía puede ignorarlo de forma explícita mediante recursos como std::ignore, eludiendo así la operación de limpieza.
Ejemplo completo¶
#include <tuple> // std::ignore
class [[nodiscard]] A {};
class B {
public:
[[nodiscard]] bool isOk() const { return true; }
};
// no need for nodiscard, A is nodiscard
A foo() {
return A();
}
// B is not nodiscard, mark it explicitly
[[nodiscard]] B bar() {
return B();
}
int main()
{
foo(); // warning: ignoring temporary created by a constructor declared with 'nodiscard' attribute
bar(); // warning
std::ignore = foo(); // ok
auto b = bar(); // ok
b.isOk(); // warning
if (b.isOk()) {} // ok
}
Temas relacionados¶
- C++17 std::string_view | C++那些事
- Recursos de memoria PMR en C++17 | C++那些事
- Diecisiete características avanzadas de C++17 | C++那些事
- Deducción de argumentos de plantilla de clase CTAD en C++17 | C++那些事
- C++17 optional_ref | C++那些事
- C++17 std::variant | C++那些事
- Vinculaciones estructuradas en C++17 | C++那些事
- Deducción con auto en plantillas de C++17 | C++那些事
- Plantillas de variable en C++17 | C++那些事