C ++ 17には[[nodiscard]]
属性が導入されており、プログラマーは、返されたオブジェクトが呼び出し元によって破棄された場合にコンパイラーが警告を生成する方法で関数をマークできます。同じ属性をクラスタイプ全体に追加できます。
私は元の提案でこの機能の動機について読んだことがあり、C ++ 20が属性をのような標準関数に追加することを知っていますstd::vector::empty
。その名前は戻り値に関する明確な意味を伝えません。
これはクールで便利な機能です。実際、それはほとんど便利すぎるようです。私が読んだ[[nodiscard]]
すべての場所で、人々はあなたがそれを選択したいくつかの関数または型に追加し、残りを忘れるかのように議論しています。しかし、特に新しいコードを書くとき、なぜ破棄不可能な値が特別な場合である必要がありますか?通常、破棄された戻り値はバグではなく、少なくともリソースの無駄ではありませんか?
そして、コンパイラができるだけ多くのエラーをキャッチする必要があるというのは、C ++自体の設計原則の1つではありませんか?
もしそうなら[[nodiscard]]
、独自の非レガシーコードをほぼすべての非void
関数とほぼすべてのクラスタイプに追加してみませんか?
私は自分のコードでそれをやろうとしましたが、非常に冗長で、Javaのように感じ始めることを除いて、うまく動作します。意図をマークする他のいくつかの場合を除いて、デフォルトで破棄された戻り値について コンパイラーに警告させるほうがはるかに自然に思えます[*]。
標準提案、ブログエントリ、Stack Overflowの質問、またはインターネット上の他の場所では、この可能性に関する議論がゼロであるため、何かが足りないはずです。
新しいC ++コードでは、なぜそのような仕組みが意味をなさないのでしょうか?冗長性は、[[nodiscard]]
ほとんどどこでも使用しない唯一の理由ですか?
[*]理論的には、[[maydiscard]]
代わりに属性のようなものがありprintf
、標準ライブラリの実装のように関数にさかのぼって追加することもできます。
const
で「単純な」クラス(または「古いデータオブジェクト」)を大幅に増大させる可能性があります。
std::vector
またはのような標準ライブラリクラスに関連std::unique_ptr
がありますが、クラス定義にデータメンバーが必要なだけです。私は両方の言語で働いてきました。Javaは大丈夫な言語ですが、より冗長です。
operator =
例えば。そしてstd::map::insert
。