69

C++ コア ガイドラインが最近発表されました (おめでとうございます!)。私はgsl::not_null型について心配しています。I.12で述べたように: null であってはならないポインターを次のように宣言します。not_null

nullptr エラーの逆参照を回避するため。nullptr の冗長なチェックを回避してパフォーマンスを向上させるため。

...

ソースに意図を記載することで、実装者とツールは、静的分析を通じていくつかのクラスのエラーを見つけるなど、より優れた診断を提供し、分岐や null テストを削除するなどの最適化を実行できます。

意図は明らかです。ただし、そのための言語機能は既に用意されています。null にできないポインターは、参照と呼ばれます。また、一度作成された参照は再バインドできませんが、この問題は によって解決されstd::reference_wrapperます。

gsl::not_nullとの主な違いはstd::reference_wrapper、後者はポインターの代わりにのみ使用できることですが、前者は割り当て可能なものすべてで機能しnullptrます (F.17 からの引用 : 「null」が有効な値ではないことを示すには、not_null を使用してください):

not_null組み込みポインターだけではありません。、、、、およびその他のポインターのような型で機能しarray_viewます。 string_viewunique_ptrshared_ptr

次のような機能比較表を想像します。

T&:

  • 保存できませんnullptrか?-はい
  • 再バインド可能? -いいえ
  • ポインター以外の代わりに使用できますか? -いいえ

std::reference_wrapper<T>:

  • 保存できませんnullptrか?-はい
  • 再バインド可能? -はい
  • ポインター以外の代わりに使用できますか? -いいえ

gsl::not_null<T*>:

  • 保存できませんnullptrか?-はい
  • 再バインド可能? -はい
  • ポインター以外の代わりに使用できますか? -はい

最後に、ここに質問があります:

  1. これらの概念の違いについての私の理解は正しいですか?
  2. std::reference_wrapperそれはもう駄目ということですか?

PS私はタグを作成cpp-core-guidelinesしましguideline-support-libraryた。これについては、適切に願っています。

4

2 に答える 2

11

std::reference_wrapperでカバーされていないユースケースがまだあると思いますgsl::not_null。基本的に、std::reference_wrapperは参照をミラーリングしてoperator T&変換を行いnot_nullますが、 は とのポインター インターフェイスを持ちますoperator->。すぐに頭に浮かぶユースケースの 1 つは、スレッドを作成するときです。

void funcWithReference(int& x) { x = 42; }
int i=0;
auto t = std::thread( funcWithReference, std::ref(i) );

を制御funcWithReferenceできない場合は、使用できませんnot_null

同じことがアルゴリズムのファンクターにも当てはまり、バインディングにboost::signalsも使用する必要がありました。

于 2015-10-24T07:32:47.090 に答える