首页 > 解决方案 > 允许备份/恢复对象值的通用类

问题描述

标准库中是否已经有任何工具允许我定义一个类型的对象,T其值可以备份和恢复?

我想这样的事情:

namespace detail
{
    template<bool b>
    using bool_constant = std::integral_constant<bool, b>;

    template<typename T, typename... Args>
    void construct_in_place(T& obj, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Args...>)
    {
        ::new (const_cast<void*>(static_cast<void const volatile*>(std::addressof(obj))))
            T(std::forward<Args>(args)...);
    }
} // namespace detail

template<typename T>
class restoreable
{
public:
    template<class = std::enable_if_t<std::is_default_constructible_v<T>>>
    restoreable() {}

    template<typename... Args,
        class = std::enable_if_t<std::is_constructible_v<T, Args...>>>
    constexpr explicit restoreable(std::in_place_t, Args&&... args)
        : m_value(std::forward<Args>(args)...)
    {}

    template<typename U>
    using allow_direct_conversion = detail::bool_constant<
        std::is_constructible_v<T, U>
        && !std::is_same_v<std::decay_t<U>, std::in_place_t>
        && !std::is_same_v<std::decay_t<U>, restoreable>>;
    template<typename U = T, std::enable_if_t<std::conjunction_v<
        allow_direct_conversion<U>,
        std::is_convertible<U, T>>, int> = 0>
    constexpr restoreable(U&& value)
        : m_value(std::forward<U>(value))
    {}

    template<typename U = T, std::enable_if_t<std::conjunction_v<
        allow_direct_conversion<U>,
        std::negation<std::is_convertible<U, T>>>, int> = 0>
    constexpr explicit restoreable(U&& value)
        : m_value(std::forward<U>(value))
    {}

    template<typename... Args>
    T& emplace(Args&&... args)
    {
        detail::construct_in_place(m_value, std::forward<Args>(args)...);
        return m_value;
    }

    void backup() { m_backup = m_value; }
    void restore() { m_value = m_backup; }

    constexpr T& value() & { return m_value; }
    constexpr T const& value() const& { return m_value; }

    constexpr T&& value() && { return std::move(m_value); }
    constexpr T const&& value() const&& { return std::move(m_value); }

private:
    T m_backup, m_value;
}; // class restoreable

标签: c++templatesgenericsc++17

解决方案


推荐阅读