[解決済み] C++14の自動復帰型控除はいつ使うべきですか?
質問
GCC 4.8.0がリリースされ、C++14の一部である自動戻り型控除をサポートするコンパイラを手に入れました。とは
-std=c++1y
, こんなことができるんです。
auto foo() { //deduced to be int
return 5;
}
質問ですが、この機能はどのような場合に使うべきですか?いつ必要で、いつコードがきれいになるのでしょうか?
シナリオ1
最初に思いつくのは、可能な限りというシナリオです。この方法で書ける関数はすべてそうすべきです。この方法の問題点は、必ずしもコードが読みやすくなるとは限らないということです。
シナリオ2
次のシナリオは、より複雑な戻り値の型を避けることです。非常に軽い例として
template<typename T, typename U>
auto add(T t, U u) { //almost deduced as decltype(t + u): decltype(auto) would
return t + u;
}
しかし、戻り値の型を明示的にパラメータに依存させることで、場合によってはより明確になることもあると思います。
シナリオ3
次に、冗長性を防ぐために。
auto foo() {
std::vector<std::map<std::pair<int, double>, int>> ret;
//fill ret in with stuff
return ret;
}
C++11では、時々、単に
return {5, 6, 7};
をベクターの代わりに指定する必要がありますが、これはいつもうまくいくとは限らず、関数ヘッダーと関数本体の両方で型を指定する必要があります。これは純粋に冗長であり、戻り値の自動的な型控除はその冗長性から我々を救ってくれる。
シナリオ4
最後に、非常に単純な関数の代わりに使用することができます。
auto position() {
return pos_;
}
auto area() {
return length_ * width_;
}
しかし、時には、正確な型を知りたいと思いながら関数を見ることもあり、そこで提供されていない場合は、コードの別の箇所、例えば
pos_
が宣言されています。
結論
これらのシナリオを並べてみて、実際にこの機能がコードをきれいにするのに役立つと証明できるものはどれでしょうか?私がここで言及するのを忘れていたシナリオはどうでしょうか?この機能を使う前に、後で噛みつかれないようにするために、どんな予防策を取るべきでしょうか?この機能がもたらしてくれる新しいことで、この機能がなければできないことはありますか?
<サブ 複数の質問は、この質問に答えるための視点を見つけるための補助的なものであることに注意してください。
どのように解決するのですか?
C++11では、ラムダでいつ戻り値の型控除を使うか、そして、いつ
auto
変数があります。
CとC++03におけるこの質問に対する従来の答えは、「文の境界では型を明示し、式の中では通常は暗黙だが、キャストで明示することができる」でした。C++11とC++1yでは、新しい場所で型を省略できるように、型控除ツールが導入されています。
申し訳ないが、一般的なルールを作って正面から解決するのは無理だろう。特定のコードを見て、あちこちに型を指定することが可読性を高めるかどうかを自分で判断する必要があります。「"このものの型はX"」とするのがコードにとって良いのか、「"このものの型はコードのこの部分の理解には無関係で、コンパイラが知る必要があり、おそらく解決できますがここで言う必要はありません"」というのがコードにとって良いのでしょうか?
読みやすさは客観的に定義できるものではなく[*]、さらに読み手によって異なるので、スタイルガイドでは完全に満たすことができない責任をコードの著者/編集者として負っているのです。スタイル・ガイドが規範を規定していたとしても、人によって好む規範は異なり、慣れないものは読みにくいと感じる傾向があります。そのため、あるスタイルルールの可読性は、他のスタイルルールの文脈の中でしか判断できないことが多いのです。
あなたのシナリオはすべて(最初のものでさえ)、誰かのコーディングスタイルに使用することができます。個人的には、2番目のケースが最も説得力のある使用例だと思いますが、それでも、ドキュメント作成ツールに依存することが予想されます。関数テンプレートの戻り値の型が次のようなものであることを文書化することは、あまり有益ではありません。
auto
というドキュメントがあるのに対して
decltype(t+u)
は、あなたが信頼できる公開されたインターフェイスを作成します(期待)。
[時折、誰かが客観的な測定を行おうとすることがあります。統計的に有意で一般的に適用可能な結果を出す人がいるとしても、それは現役のプログラマーには完全に無視され、何が読みやすいかについての作者の直感が優先されます。
関連
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
-
[解決済み] C++でクラスと構造体はいつ使い分けるべきか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++