答えて
本質的には、comparisonsまたはboolean conversionのvolatile shared_ptr
では標準が満たされていません。
コンパイルするfollowing fails ...
auto main() -> int {
volatile shared_ptr<int> a;
if (a == nullptr) // fails
; // empty
if (a) // fails
; // empty
}
あなたは(経由。const_cast
)volatile
オフを唱えたが、私はそれが望ましい結果を持っていますかわかりません。 cppreferenceから:
非
const
アクセス経路を通してconst
オブジェクトを変更し、未定義の動作に非volatile
glvalue結果を通じてvolatile
オブジェクトを参照します。それはあったが、その後、適切な方法や場合 -volatile
としてメンバメソッドをマークしないで、クラスやライブラリ実装者が効果的に「これはvolatile
オブジェクトとして使用することを意図するものではない」と言っているより一般的に言えば
、オーバーロードはvolatile
個のオブジェクトを提供します。同様に、これはconst
としてメンバーをマークするには、const
に適用され、彼らは「このクラスはconst
オブジェクトとして使用することができます。
がなぜ必要なvolatile
、外部のどのようなソースがshared_ptr
を変更することができている」と言っているの知識がなくても(これはvolatile
の使用の1つです)スレッドの問題がある場合は、スレッドライブラリユーティリティを使用する方が良いでしょう。あるいは単に最適化をオフにしているだけの場合は、さまざまなコンパイラがこれについてのメカニズムを持っています(プラグマなど)。
良い点ですが、std :: atomicを使用するのはC++ 11で揮発性より完璧です。 – Atifm
Volatileは、予期せずメモリが変更される可能性があることをコンパイラに示すものです。いくつかの最適化を無効にします。その下にはちょうどメモリアドレスが含まれています。
共有ポインターはリソースを保持/管理しているだけです。つまり、std :: shared_ptr :: get()はvolatileとマークされていないので、実際にはshared_ptrを使用してアクセス可能な方法でvolatileポインタを管理することはできません。
裸のポインタを使用し、スコープ付き出口またはデストラクタを使用してその後ろをクリーンアップすることをお勧めします。
volatileを使用していて、ポインタが別のスレッドによって変更される可能性がある場合は、volatileの代わりにstd :: atomicを使用することをお勧めします。スレッドのワークフローでは、std::atomicの前に、他のスレッドからアクセスされたポインタは通常volatileとマークされました。それはもはやベストプラクティスではありません。
実際には揮発性は示唆ではありません。それが行うことの1つは、揮発性オブジェクトのすべてのアクセス(読み取りまたは書き込み操作、メンバー関数呼び出しなど)は、最適化の目的で目に見える副作用として扱われます(つまり、 – NathanOliver
この関数には揮発性の修飾子がないので、volatileオブジェクトで呼び出すことはできません.... – cpplearner
@nathanOliverはあなたの提案通りに改名しました。 – Atifm
「volatile」は移植可能なスレッド同期メカニズムではないことに注意してください(おそらく一部の環境では十分かもしれません)。通常はメモリマップされたI/Oと同様のメカニズムと共に使用され、これは 'shared_ptr'のための不思議な場所です。たぶん*あなたが揮発性のshared_ptrを持つ理由を明らかにするべきでしょう。 – peterchen
@peterchen http://cxx.isvolatileusefulwiththreads.com/ –
@MikeVine:優秀!そのリンクを覚えています。(変更があった場合は毎日確認してください) – peterchen