2015-11-10 2 views
5

Когда я использую unique_ptr в качестве возвращаемого типа, я получаю Ошибка компилятора C2280:Могу ли я использовать интеллектуальные указатели C++ 11 как тип возвращаемого сообщения в C++ Actor Framework?

'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++ примеров Actor Framework):

#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. – mavam

+0

@MatthiasVallentin, если я понимаю, что вы говорите, то мой ниже ответ неверен (это просто происходит для компиляции). Если вы добавите свой комментарий в ответ, я с радостью приму это! –

ответ

4

CAF требует, чтобы каждый тип в сообщении является регулярным. Это означает, что он должен предоставить конструктор копирования, который не имеет std::unique_ptr. Поэтому компилятор жалуется.

сообщения имеют реализацию копирования при записи. Вы можете дешево скопировать одно сообщение, так как оно просто ударяет счетчик ссылок внутри. В любое время вы можете выполнять const-доступ элементов сообщения. «Запись» части «копирование на запись» срабатывает только в том случае, если ссылочный счет сообщения больше 1 и вы запрашиваете неконстантный доступ. В этот момент среда выполнения вызывает конструктор копирования содержащегося типа для создания нового сообщения.

Если CAF безоговорочно выполнит эту копию, независимо от счетчика ссылок, тогда было бы невозможно эффективно поддерживать программирование потока данных, когда актер получает сообщение, изменяет его содержимое и переходит на следующий этап.

Думает сообщения, как указатели контейнеры: содержащиеся в нем элементы, которые выделяются на свободном магазине. Хранение указателя в сообщении обычно является недостатком дизайна. Двойная упаковка также требует излишнего распределения распределителя.

Поскольку вы можете порезать сообщения гибко, вы уйти с созданием одного сообщения, а затем может использовать содержащуюся значение в различных контекстах.

2

Да, C++ Actor Framework позволяет интеллектуальным указателям возвращать сообщения, но не в форме unique_ptr.

Реализация реализации C++ Actor Framework в настоящее время делает копию сообщения и разыгрывает unique_ptr, вызывая ошибку компилятора.

Вместо использования unique_ptr используйте shared_ptr вместо этого. Счетчик ссылок будет 2 при изменении кода примера вопроса. Я также использовал функцию пользовательского удаления, чтобы убедиться, что память выпущена как ожидалось, несмотря на создание второго share_ptr.

Смежные вопросы