A recursive_wrapper<T>
represents
a heap-allocated instance of T
.
Recursive wrapper is very useful, but you shouldn't normally create a recursive_wrapper
yourself, instead that
happens internally within a variant
.
namespace strict_variant { template <typename T> class recursive_wrapper { T * m_t; void destroy() { delete m_t; } public: ~recursive_wrapper() noexcept { this->destroy(); } template <typename... Args> recursive_wrapper(Args &&... args) : m_t(new T(std::forward<Args>(args)...)) {} recursive_wrapper(recursive_wrapper & rhs) : recursive_wrapper(static_cast<const recursive_wrapper &>(rhs)) {} recursive_wrapper(const recursive_wrapper & rhs) : m_t(new T(rhs.get())) {} // Pointer move recursive_wrapper(recursive_wrapper && rhs) noexcept // : m_t(rhs.m_t) // { rhs.m_t = nullptr; } // Not assignable, we never actually need this, and it adds complexity // associated to lifetime of `m_t` object. recursive_wrapper & operator=(const recursive_wrapper &) = delete; recursive_wrapper & operator=(recursive_wrapper &&) = delete; T & get() & { STRICT_VARIANT_ASSERT(m_t, "Bad access!"); return *m_t; } const T & get() const & { STRICT_VARIANT_ASSERT(m_t, "Bad access!"); return *m_t; } T && get() && { STRICT_VARIANT_ASSERT(m_t, "Bad access!"); return std::move(*m_t); } };
Caution | |
---|---|
After a
This is different from
See Implementation
Notes for a discussion of why it is this way and how |