2016-05-28 7 views
3

私は最適化する必要のある小さなコードセグメントを持っています。スレッド 'A'は、ヒープオブジェクトへのboost_sharedを作成しました。スレッド 'A'はshared_ptrをスレッドセーフキューに書き込みます。スレッド 'B'はshared_ptrを読み取り、それを使用して破棄します。参照を介してboost :: shared_ptrのエイリアスを作成する

プロファイリング/テストが徹底的に行われることで、キューに出入りするshared_ptrのコピーと参照カウントの調整にコストがかかります。したがって、私は参照を介してキューに共有ptrを渡したいと思います。また、shared_ptrを新しいshared_ptrを構築するのではなく、キューに移動するためにstd :: moveを使用したいと思います(キューに渡されたshared_ptrパラメータが無効になることがわかります)。

多変量のダッシュに混ぜるまで、説明されているすべてがうまく動作します。 refでshared_ptrを派生objに渡して、shared_ptrをベースクラスに期待する関数に渡すことはできません。私はこれを、私を混乱させるような行動を露呈する非常に小さな切り札に煮詰めました。

#include <boost/shared_ptr.hpp> 

class Base 
{ 
}; 

class Derived : public Base 
{ 
}; 

int main() 
{ 
    boost::shared_ptr<Derived> pDerived(new Derived()); // simple creation 
    boost::shared_ptr<Derived> &alias1 = pDerived;  // works fine 
    const boost::shared_ptr<Base> &alias2 = pDerived; // also works fine 
    boost::shared_ptr<Base> &alias3 = pDerived;   // compilation error 

    //native pointers 
    Derived *alias4 = pDerived.get();  //works 
    const Base *alias5 = pDerived.get(); //works 
    Base *alias6 = pDerived.get();  //works 

    //native references 
    Derived &alias7 = *pDerived;   // works 
    const Base &alias8 = *pDerived;  // works 
    Base &alias9 = *pDerived;    // works 
} 

alias2への割り当ては完全に大丈夫です、まだAlias3というの割り当てはコンパイラエラーを生成する理由を私は理解していません。誰かがこれを説明できますか?私はalias3の例のような機能が必要であり、動作させることはできません。

+0

'のstd :: shared_ptrの&Alias3という= static_castを<はstd :: shared_ptrの>(pDerived);' – user2296177

+0

あなたはまた、ブーストを使用するように試みることができる 'static_cast':' Alias3という=後押し:: static_pointer_cast (pDerived); ' – pingul

+0

Eissa N.と同様に、キャストの結果、コンパイルエラーが発生します。 ''âboost:: shared_ptr型の非const参照の無効な初期化がâboost:: shared_ptrタイプ¡ のタイプの値であり、boost :: shared_ptr &alias3 = boost :: static_pointer_cast (pDerived); 'これが機能したとしても、効率的な理由から、一時的なrvalオブジェクトの作成は避けようとしています。 – njensen

答えて

0

この問題は、ブーストまたはスマートポインタには関係しません。次の簡単な例に示すように、それはあまりにもPOD型で起こることができます。

int main() { 
    int x = 0; 
    const double &y = x; //fine 
    double &z = x; //error! 
    return 0; 
} 

を理由は、一時的な値(右辺値)がconst&に特異的に結合することができますが、それは&にバインドすることができないということです。 double &z = xで起こることは、xzは無関係のタイプであり、xdoubleに変換する必要があり、&にバインドできない一時変数が作成されることです。

+0

Eissa N. - あなたは完全に正しいと思う。ありがとうございました。ただし、この例に追加された追加の行を参照してください。ネイティブポインタと参照は、あなたが示唆するように一時的なrvalの作成を必要としていないようです(おそらく、コンパイラが連結構造体のメンバオフセットをネイティブに理解しているためです)。多分これは、shared_ptrのコンテナ/テンプレートがネイティブの相手のクリーンな置換ではないという別の方法です。 – njensen

+0

@njensen生ポインタとスマートポインタを比較する場合、 'Derived * pDerived = new Derived;をチェックする必要があります。 Base *&alias = pDerived; 'は再び失敗します。 –

+0

できれば私はあなたに投票します。明らかに私は投票数を得るには新しすぎです。私はあなたの最後の例が問題を正確に公開していることに同意します。 – njensen

関連する問題