Extends std::enabled_shared_from_this. Offers weak_from_this() to pre-C++17 code. Use as drop-in replacement for std::enable_shared_from_this.
C++14 has no direct means of creating a std::weak_ptr, one must always create a (temporary) std::shared_ptr first. C++17 adds weak_from_this() to std::enable_shared_from_this to avoid that overhead. Alas code that must compile under different language versions cannot call std::enable_shared_from_this::weak_from_this() directly. Hence this class.
class MyClass : public folly::enable_shared_from_this<MyClass> {};
int main() { std::shared_ptr<MyClass> sp = std::make_shared<MyClass>(); std::weak_ptr<MyClass> wp = sp->weak_from_this(); }
#pragma once
#include <memory>
#if __cplusplus >= 201700L || __cpp_lib_enable_shared_from_this >= 201603L
using std::enable_shared_from_this;
#else
template <typename T>
class enable_shared_from_this : public std::enable_shared_from_this<T> {
public:
return weak_from_this_<T>(this);
}
return weak_from_this_<T>(this);
}
private:
template <typename U>
-> decltype(base_ptr->weak_from_this()) {
return base_ptr->weak_from_this();
}
template <typename U>
auto weak_from_this_(std::enable_shared_from_this<U>
const* base_ptr)
const noexcept -> decltype(base_ptr->weak_from_this()) {
return base_ptr->weak_from_this();
}
template <typename U>
try {
return this->shared_from_this();
} catch (std::bad_weak_ptr const&) {
return std::weak_ptr<U>{};
}
}
template <typename U>
try {
return this->shared_from_this();
} catch (std::bad_weak_ptr const&) {
return std::weak_ptr<U const>{};
}
}
};
#endif
}