問題タブ [effective-c++]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - スワップの実装: 効率と適用範囲は?
swap
すべての関数の実装をカバーしようとしています。
関数の次の実装ではswap
、2 つのパラメーターの値を交換するための一時変数は必要ありません。
また
また
したがって、使用メモリに関しては、次の場合よりも効果的です。
一方、swap
次を使用して実装できます。
既存のすべての実装を比較し、それらの適用範囲を理解しようとしています。
c++ - Scott Meyers の std::weak_ptr の例の要点を正しく理解できましたか?
効果的な最新の C++ (136 ページ) では、次の例を使用してstd::weak_ptr
. キャッシュは、オブジェクトへの弱いポインターを値として持つ順序付けられていないマップとして定義されます。このキャッシュのクライアントが (キーによって) オブジェクトを要求するたびに、対応するウィーク ポインターが検索さlock()
れ、それに対して呼び出されます。結果std::shared_ptr
が でない場合はnull
、それが返されます。それ以外の場合、オブジェクトは外部データベースから再ロードされ、キャッシュに入力されてstd::shared_ptr
返されます。
ここで質問: を使用せずにこれを実装することは可能であると考えるかもしれませんがstd::weak_ptr
、代わりに強力な共有ポインターをキャッシュ値として格納します。use_count()
強いポインタの が 1 に等しい場合、それはすべてのクライアントのポインタが破棄されたことを意味します。この例の要点は、std::weak_ptr
実際にオブジェクトを削除することでメモリを節約できるということでしょうか?
c++ - Scott Meyer のより効果的な C++ 項目 22 の適切な実装でユニバーサル参照を回避する:「スタンドアロン op の代わりに op= を使用することを検討してください」?
私は、より効果的な C++ の項目 22 にある Scott Meyers のアドバイスに従おうとしています:「op=
スタンドアロンではなく使用を検討してくださいop
」。彼は、 のテンプレートを作成してoperator+
、実装するすべてのクラスがoperator+=
自動的に を取得できるようにすることを提案していoperator+
ます。
さて、Effective Modern C++ の項目 25 には、行列の加算の例 (pg. 172) があります。そこでは、右辺値を使用したオーバーロードoperator+
が提案されていますlhs
。rhs
おそらく巨大な行列の無用なコピー。だから私はオーバーロードを追加しました:
ここでの問題は、それT&&
が普遍的な参照であり、すべてをキャプチャすることになるため、左辺値から移動することになりますが、これは望ましくない動作です。
operator+
では、テンプレートを適切に実装するにはどうすればよいでしょうか。
値渡しを使用した部分的な解決策:アイテム 41: "コピー可能なパラメーターの値渡しを検討してください..." も読んだので、Effective Modern C++ から、次のような独自のバージョンを作成しようとしました。
しかし、rhs が右辺値の場合、これは最適化の機会を逃します。この場合、rhs を使用して結果を格納しないからです。したがって、これは部分的な解決策にすぎません。
c++ - 自動型推論の定数
Scott Meyers の「Effective modern C++」を読んでいます。項目 1 には、次の例が含まれています。
項目 3 には、次の例が表示されます。
項目 1 に基づいて、私はmyWidget1
のタイプが であると予想しましconst Widget
た。何か不足していますか?
c++ - 末尾の戻り値の型と右辺値
Scott Meyers の『Effective Modern C++ 』を読んでいて、 Deducing Typesの章で彼が提供している例を自分のマシンで試しています。
彼はこの機能を提供します:
そして、この関数を次のように使用します。
コンパイルされないと言っています。MSVC で試してみたところ、コンパイルできました。に次のように書きましたmain
。
それがコンパイルされる理由がわかりません。何よりも10
、両端キューの最初の要素として表示されます。彼の説明によると、このコードは間違っています。なぜここで機能するのですか?私は何が欠けていますか?
c++ - 普遍的な型の演繹 スコット・マイヤーズ
私はスコット・マイヤーズによるEffective modern C++を読んでいます
関数パラメーターであるユニバーサル参照の場合、初期化子は呼び出しサイトで提供されます。
参照が普遍的であるためには、型推論が必要ですが、それだけでは十分ではありません。参照宣言の形式も正しい必要があり、その from はかなり制約されています。正確に " " でなければなりませんT&&
。
f が呼び出されると、型T
が推定されます (呼び出し元が明示的に指定しない限り、私たちは気にしません)。しかし、param の型宣言の形式は " T&&
" ではなく、" std::vector<T>&&
" です。これにより、 param が普遍的な参照である可能性が排除されます。したがって、 param は右辺値参照であり、左辺値を渡そうとすると、コンパイラが喜んで確認します。f
上記では、次の質問があります
- 作成者が「呼び出し元が明示的に指定しない限り、私たちが関与しないエッジケース」とはどういう意味ですか? 作成者が発信者が明示的に指定していると言及しているエッジケースとは何かの例を提供するように要求します
c++ - C++ scott meyers でイベントを検出する際の条件変数の使用
以下のScott Meyersの本でEffective Modern C ++の条件変数について読んでいます。
ここで著者は以下のように述べています
ミューテックスは共有データへのアクセスを制御するために使用されますが、検出タスクと反応タスクがそのような仲介を必要としない可能性は十分にあります。たとえば、検出タスクはグローバル データ構造の初期化を担当し、それを反応タスクに引き渡して使用する場合があります。検出タスクが初期化後にデータ構造にアクセスしない場合、および検出タスクが準備完了を示す前に反応タスクがアクセスしない場合、2 つのタスクはプログラム ロジックを通じて互いの邪魔にならないようにします。ミューテックスは必要ありません。
上記のテキストについて、私は理解するのが難しい
著者が「2 つのタスクがプログラム ロジックを介して互いの邪魔にならないようにする」とはどういう意味ですか?
作成者がミューテックスを必要としないとはどういう意味ですか?
c++ - なぜEffective C++で宣言と定義がこのように定義されるのですか?
Effective C++ (第3 版)、項目 2 (Preferおよびto )const
では、クラス固有の定数のコード セグメントは次のように読み取られます。enum
inline
#define
この本は、(私自身の言葉で) それstatic const int NumTurns = 5;
は、アドレスが決して使用されない静的な整数定数でない限り、クラス メンバーに対して C++ で通常必要とされる定義ではないと述べています。上記が定数に当てはまらない場合、またはコンパイラが何らかの理由で定義を要求する場合は、次のように定義を実装ファイルで提供する必要があります。
この本によると (私自身の言葉でも)、値は宣言で既に指定されているため、定義には値が指定されていません。
これは、宣言と定義の定義について私がすでに知っていると思っていたことを混乱させています (そして、この質問をする前に Google で再確認しました):
static const int NumTurns = 5
定義がないのはなぜですか?NumTurns
ここの値に初期化されていませ5
んし、宣言と定義が一緒になった場合を初期化というのではないでしょうか。- なぜ
static
整数定数は定義を必要としないのですか? - 値が定義されていない場合、2 番目のコード スニペットが定義と見なされるのはなぜですか?
- 初期化は定義ではありませんか?ここで「唯一の定義」ルールに違反しないのはなぜですか?
この時点で私は自分自身を混乱させている可能性があるので、誰かが親切に私をゼロから再教育できますか: なぜこれらの 2 行のコード宣言と定義が他の行ではなく、初期化のインスタンスがあるのですか? 初期化も定義ですか?
クレジット: コード スニペットは本から直接引用されています。
- 宣言は、識別子と型を導入します
- 定義はインスタンス化して実装します
だから、ええ...それはここで起こっていることではないようです.
編集 2 : コンパイラが静的整数定数をメモリ内に格納せず、コード内でインラインに置き換えるだけで最適化できる可能性があると考えています。しかし、NumTurns
アドレスが使用されている場合、インスタンス化が既に存在するため、宣言が宣言 + 定義に自動的に変更されないのはなぜですか?
編集3:(この編集は元の質問とはあまり関係がありませんが、まだ未解決です。以下の各回答のコメントにコピーして貼り付ける必要がないように、ここに配置します。これについて回答してくださいコメントで. ありがとう!)
答えてくれてありがとう。私の頭は今でははるかに明確になりましたが、編集 2 からの最後の質問はまだ残っています: コンパイラが定義が必要なプログラム内の条件を検出した場合 (たとえば、プログラムで使用されている場合)、なぜ自動的に再解釈し&NumTurns
ないのですか?static const int NumTurns = 5;
宣言のみではなく宣言と定義?プログラム内の他の場所の定義が持つすべての構文があります。
私は学校で Java のバックグラウンドを持っており、上記の方法で静的メンバーに対してこのような個別の定義を作成する必要はありませんでした。C++が違うのはわかっているのですが、上記がどうしてこうなるのか知りたいです。アドレスが使用されていない場合にインラインで置換される静的な整数メンバーは、基本的な機能というよりも最適化のように聞こえますが、なぜそれを回避する必要があるのですか (条件が使用されていない場合に定義として別のステートメントを提供する)元のステートメントの構文で十分であるにもかかわらず満たされる) 逆の方法ではなく (構文が十分であるため、必要なときに元のステートメントを定義として扱うコンパイラー)?