Почему enable_shared_from_this не имеет прямого доступа к встроенному слабому_птру?

Я хочу использовать boost сигналы2 с автоматическим управлением подключением в многопоточном приложении. Мой класс наследует от enable_shared_from_this<> и я хочу подключить метод-член из другого метода-члена. Соединение может часто перестраиваться, поэтому мой код должен быть настолько быстрым, насколько это возможно (несмотря на саму производительность сигналов сигнала2):

typedef boost::signals2::signal<void ()> signal_type;

struct Cat : public enable_shared_from_this<Cat>
{
void meow ();

void connect (signal_type& s)
{
// can't write this
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));

// ok, but slow?! two temporary smart pointers
weak_ptr<Cat> const myself (shared_from_this ());
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (myself));
}

// i am missing something like this in the base class
// protected:
//   weak_ptr<Cat> const& weak_from_this ();
};

Я знаю, что мои цели разработки могут быть противоречивыми (автоматическое управление соединениями и безопасность потоков, но также быстрый код), но в любом случае:

  1. Почему enable_shared_from_this<> отсутствие прямого доступа к встроенным weak_ptr<>? Я не вижу противоположной причины. Нет ли варианта использования, аналогичного моему?

  2. Есть ли более быстрое решение, чем приведенное выше?

Редактировать:

Я знаю, что могу сделать что-то подобное, но я хочу избежать дополнительного наказания за хранение / инициализацию:

template <typename T>
struct enable_weak_from_this : public enable_shared_from_this<T>
{
protected:
weak_ptr<T> /* const& */ weak_from_this ()
{
if (mWeakFromThis.expired ())
{
mWeakFromThis = this->shared_from_this ();
}

return mWeakFromThis;
}

private:
weak_ptr<T> mWeakFromThis;
};

2

Решение

Причина, по которой у вас нет доступа к weak_ptr в том, что enable_shared_from_this не должен использовать один. Иметь weak_ptr это просто один возможный реализация enable_shared_from_this, Это не единственный.

поскольку enable_shared_from_this является частью той же стандартной библиотеки, что и shared_ptrможно использовать более эффективную реализацию, чем непосредственное хранение weak_ptr, И комитет не хочет предотвращать эту оптимизацию.

// хорошо, но медленно ?! два временных умных указателя

Это только один временный умный указатель. Копия elision / motion должна заботиться обо всем, кроме первого объекта.

2

Другие решения

Это может быть потому, что нет shared_ptr ссылаясь на Cat пример. weak_ptr требует, чтобы был хотя бы один активный shared_ptr,

Попробуйте разместить shared_ptr в качестве переменной-члена и назначить ей сначала в connect метод:

typedef boost::signals2::signal<void ()> signal_type;

struct Cat : public enable_shared_from_this<Cat>
{
void meow ();
boost::shared_ptr<Cat> test;

void connect (signal_type& s)
{
test = shared_from_this();
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
}
};

Но в принципе не может быть никакого weak_ptr если нет shared_ptr,
И если все shared_ptr исчезнуть в то время как weak_ptr все еще используется, то weak_ptr может указывать на несуществующий объект.

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

-1