プログラミング言語C++において、nodiscard
属性が指定された関数に対し意図的な戻り値破棄を明示する方法。
2024-07-05追記:C++2c(C++26)において提案文書P2968R2が採択され*1、方式(3) std::ignore
への戻り値代入は明確にwell-definedとされる。
まとめ:
- C++23現在は、方式(3)
std::ignore
への関数戻り値代入が実践的か。*2 - C++2c以降は、方式(4) プレースホルダ識別子
_
(アンダースコア1文字)への関数戻り値代入も候補となる。 - 方式(3), (4)は戻り値オブジェクトの破棄タイミングが異なることに注意。
// 戻り値の破棄をすべきでない関数 [[nodiscard]] int f() { return 42; } f(); // コンパイラによる警告(warning) // GCC: ignoring return value of 'int f()', declared with attribute 'nodiscard' [-Wunused-result] // Clang: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result] // 意図的な戻り値破棄を明示 (void)f(); // (1) OK, but... static_cast<void>(f()); // (2) OK, but... std::ignore = f(); // (3) OK auto _ = f(); // (4) OK(C++2c)
各方式の問題点は下記の通り:
- 方式(1) well-definedだが、現代では利用推奨されないCスタイルキャストを利用している。
- 方式(2) well-definedだが、冗長な記述となっておりプログラマ意図を読み取りづらい。
方式(3) C++ Core Guildlineでは方式(1),(2)の代替案とされる。Language Lawyer*3による厳密解釈では微妙とのウワサ。*4
関連URL
- (PDF) P2169R4 A Nice Placeholder With No Name
- P2968R2 Make std::ignore a first-class object
- P2992R0 Attribute [[discard]] and attributes on expressions
- [C++]名前を必要としない変数のための変数名 - 地面を見下ろす少年の足蹴にされる私
- c++ - std::ignore for ignoring unused variable - Stack Overflow
- https://twitter.com/yohhoy/status/1711400241092800714
*1:https://github.com/cplusplus/papers/issues/1640
*2:https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es48-avoid-casts
*3:https://meta.stackoverflow.com/questions/256510/
*4:P2968R2より引用: "All major open source C++ library implementations provide a suitably implemented std::ignore allowing a no-op assignment from any object type. However, according to some C++ experts the standard doesn’t bless its use beyond std::tie."