2015-11-10 12 views
5

私は戻り値の型としてunique_ptrをを使用する場合、私はコンパイラエラーC2280を受け取る:C++ ActorフレームワークでメッセージリターンタイプとしてC++ 11のスマートポインタを使用できますか?

'caf::detail::tuple_vals<std::unique_ptr<A,std::default_delete<_Ty>>>::tuple_vals(const caf::detail::tuple_vals<std::unique_ptr<_Ty,std::default_delete<_Ty>>> &)': attempting to reference a deleted function include\caf\detail\tuple_vals.hpp 102 

は、ここで(C++俳優フレームワーク例の1つから変更)問題を示しているいくつかのサンプルコードです:

#include <iostream> 
#include "caf/all.hpp" 

using namespace caf; 
using namespace std; 

class A 
{ 
public: 
    int a; 

    A(int a) 
    { 
     this->a = a; 
    } 
}; 

using a_type = typed_actor<replies_to<int>::with<unique_ptr<A>>>; 

a_type::behavior_type a_behavior(a_type::pointer self) 
{ 
    return 
    { 
     [self](const int& a) -> unique_ptr<A> 
     { 
      return make_unique<A>(5); 
     } 
    }; 
} 

void tester(event_based_actor* self, const a_type& testee) 
{ 
    self->link_to(testee); 
    // will be invoked if we receive an unexpected response message 
    self->on_sync_failure(
     [=] 
     { 
      aout(self) << "AUT (actor under test) failed" << endl; 
      self->quit(exit_reason::user_shutdown); 
     }); 
    self->sync_send(testee, 5).then(
     [=](unique_ptr<A> a) 
     { 
      if(a->a == 5) 
      { 
       aout(self) << "AUT success" << endl; 
      } 

      self->send_exit(testee, exit_reason::user_shutdown); 
     } 
    ); 
} 
+0

メッセージのすべてのタイプは、規則的でなければならず、つまり値の意味を持っていなければなりません。ランタイムは、参照カウントが1より大きいメッセージ値に非constアクセスを取得しようとしたときに発生する、メッセージを切り離すときにのみコピーコンストラクタを呼び出します。 – mavam

+0

@MatthiasVallentinあなたが何を言っているのか理解していれば以下の答えは間違っています(ちょうどコンパイルが起こります)。あなたのコメントを答えにすると、私はそれを喜んで受け入れるでしょう! –

答えて

4

CAFでは、メッセージの各タイプがの正規表現であることが必要です。これは、コピーコンストラクタを提供しなければならないことを意味し、std::unique_ptrにはありません。したがって、コンパイラは不平を言う。

メッセージにはコピーオンライトが実装されています。単一のメッセージを安価にコピーすることができます。内部的に参照カウントをバンプするだけです。いつでも、メッセージ要素のconstアクセスを実行できます。コピーオンライトの「書き込み」部分は、メッセージの参照カウントが非constアクセスを要求する1 より大きい場合にのみ起動します。その時点で、ランタイムは含まれている型のコピーコンストラクタを呼び出して新しいメッセージを作成します。

CAFがリファレンスカウントとは無関係にこのコピーを無条件で実行すると、アクターがメッセージを受信して​​その内容を変更し、次のステージに転送するデータフロープログラミングを効率的にサポートすることはできません。

メッセージをポインタコンテナと考える:含まれる要素はフリーストアに割り当てられます。通常、メッセージにポインタを格納するのは設計上の欠陥です。二重ラッピングは、不必要にアロケータを強調します。

メッセージを柔軟にスライスすることができるため、単一のメッセージを作成してから、さまざまなコンテキストで含まれている値を使用できます。

2

はい、C++アクタフレームワークでは返信メッセージでスマートポインタを使用できますが、unique_ptrという形式では使用できません。

現在、C++ Actor Frameworkの実装では、メッセージのコピーが作成され、unique_ptrが参照解除され、コンパイラエラーが発生します。

代わりにunique_ptrを使用する代わりに、shared_ptrを使用してください。質問のサンプルコードを変更すると、参照カウントは2になります。また、カスタム削除機能を使用して、メモリが2番目のshare_ptrの作成にもかかわらず予想通りにリリースされたことを確認しました。

関連する問題