Вот более упрощенный пример:
#include <experimental/memory>
#include <iostream>
template <typename T>
using enable_shared_from_this = std::experimental::enable_shared_from_this<T>;
struct A : enable_shared_from_this<A> {
int a;
A() : a(7) {}
};
int main() {
auto sp = std::make_shared<A>();
auto wp = sp->weak_from_this();
if (auto s = wp.lock()) {
std::cout << s->a << std::endl;
}
}
Это ничего не печатает. Зачем? В конечном счете, причина заключается в том, что это std::enable_shared_from_this
, а не какой-то другой тип, который вы сами можете предоставить: класс shared_ptr
должен включить эту функцию. Новая функциональность является экспериментальной, поэтому std::shared_ptr
не включался - поэтому базовый weak_ptr
никогда не инициализировался. Такого просто не бывает, поэтому wp
здесь всегда "пусто" weak_ptr
.
С другой стороны, std::experimental::shared_ptr
включает подписку на эту функцию. Вам нужно использовать shared_ptr
, соответствующий вашему enable_shared_from_this
- std::experimental::shared_ptr
.
Там нет std::experimental::make_shared
(или, по крайней мере, насколько я мог найти), но механизм согласия в любом случае не основан на этом - он просто основан на любой конструкции shared_ptr
. Так что если вы измените:
auto sp = std::make_shared<A>();
до:
auto sp = std::experimental::shared_ptr<A>(new A);
Тогда механизм согласия совпадает с типом shared_ptr
и делает все правильно, вы получаете действительные weak_ptr
(std::experimental::weak_ptr
), lock()
дает вам совместное владение базовым A
и программа печатает 7.