Skip to content

Instantly share code, notes, and snippets.

@egtra
Created March 19, 2012 15:45
Show Gist options
  • Select an option

  • Save egtra/2116775 to your computer and use it in GitHub Desktop.

Select an option

Save egtra/2116775 to your computer and use it in GitHub Desktop.
コンストラクタでもshared_from_thisが使えるenable_shared_from_thisの製作
#include <iostream>
#include <memory>
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
template<typename T>
class x_enable_shared_from_this
{
public:
std::shared_ptr<T> shared_from_this()
{
return std::shared_ptr<T>(pWeakThis);
}
std::shared_ptr<T const> shared_from_this() const
{
return std::shared_ptr<T const>(pWeakThis);
}
protected:
x_enable_shared_from_this() {}
explicit x_enable_shared_from_this(std::shared_ptr<T> const& pThis)
: pWeakThis(pThis)
{
}
x_enable_shared_from_this(x_enable_shared_from_this const&) {}
x_enable_shared_from_this& operator =(x_enable_shared_from_this const&)
{
return *this;
}
~x_enable_shared_from_this() = default;
private:
std::weak_ptr<T> pWeakThis;
};
template<typename T>
class x_enable_shared_from_this_impl : public T
{
public:
template<typename... Args>
x_enable_shared_from_this_impl(std::shared_ptr<void> pThis, Args&&... args)
: x_enable_shared_from_this<T>(std::shared_ptr<T>(pThis, this))
, T(std::forward<Args>(args)...)
{
}
~x_enable_shared_from_this_impl() = default;
x_enable_shared_from_this_impl(x_enable_shared_from_this_impl const&) = delete;
x_enable_shared_from_this_impl& operator =(x_enable_shared_from_this_impl const&) = delete;
};
template<typename T, typename... Args>
std::shared_ptr<T> x_make_shared(Args&&... args)
{
auto tmp = std::make_shared<boost::optional<x_enable_shared_from_this_impl<T>>>();
*tmp = boost::in_place(tmp, std::forward<Args>(args)...);
return {tmp, tmp->get_ptr()};
}
class Hoge : public virtual x_enable_shared_from_this<Hoge>
{
public:
Hoge(int x, int y, int z)
{
auto p = shared_from_this();
std::cout << p << '\n';
std::cout << this << '\n';
std::cout << x << ' ' << y << ' ' << z << std::endl;
}
~Hoge() {}
};
int main()
{
auto p = x_make_shared<Hoge>(1, 2, 3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment