Это деталь реализации, но не могли бы вы сделать что-то неприятное с внутренним объявлением друга:
template<typename _Tp1>
friend void
__enable_shared_from_this_helper(const __shared_count<>& __pn,
const enable_shared_from_this* __pe,
const _Tp1* __px) noexcept
Реализуйте свою собственную версию с _Tp1 как weak_ptr <> *, которая возвращает слабый указатель [На самом деле нетточно так же, как __px является указателем на константу, поэтому вам нужно дополнительное косвенное обращение, чтобы потерять констант, или, если вы все равно пачкаетесь, выбросьте его!].Оберните все это в класс, из которого вы потом производите вместо enable_shared_from_this:
#if >= C++17
using enable_shared_from_this_c17 = enable_shared_from_this;
#else
template<typename _Tp>
enable_shared_from_this_c17: public enable_shared_from_this<_Tp>
{
weak_ptr<_Tp> weak_from_this()
{
weak_ptr<_Tp> rv; auto rv2 = &rv;
__enable_shared_from_this_helper(*(const __shared_count<>*)nullptr, this, &rv2);
return rv;
}
}
#endif
Теперь у вас есть реализация weak_from_this () в c ++ 14.Да, это неприятный клочок, но это только до тех пор, пока вы не обновитесь до 17.
В качестве альтернативы просто поймайте исключение!
Третий вариант - добавьте экземплярную оболочку шаблона, которая устанавливает "сконструированный"в оболочке для enable_shared_from_this, который оборачивает shared_from_this (), поэтому он терпит неудачу до тех пор, пока не будет установлен созданный флаг.
enable_shared_from_this
safe_shared_from_this
your interfaces
your_implementation
constructed<your_implementation>
Конечно, это несовершенно, если класс когда-либо используется без непосредственного присвоения shared_ptr.