c++ - 创建一个可选的元组

标签 c++ boost tuples variadic-templates option-type

我不明白为什么没有optional tuple ,我的意思是,像这样的东西; optional<int,string,char>这将结合 optional int , optional stringoptional char .

您可以将其视为优化的 std::tuple<boost::optional<T>...>

哪里booleansoptionals 使用在 structure 结束时会在一起为了打包它,或者更好的是,将其存储在一个位集中。

这可能会大大减少结构的内存,而且更优雅:

std::tuple<boost::optional<int>,boost::optional<string>,boost::optional<char>>

对比

optional<int,string,char>

我可以想出一种方法,使用 boost::optional 的实现和 variadic templates ,但在开始之前,我想知道这是否是一个好主意,实现它的更好方法是什么,我将面临哪些困难?

编辑:

基本上我不喜欢的原因std::tuple<boost::optional<T>...>;

optional<T>T 的并集和一个 bool :

enter image description here

新结构可以节省大量内存!!

最佳答案

你可以自己实现,类似于:

/**
 *  Similar to `optional`, but take the bool as argument.
 */
template <typename T>
class out_optional
{
public:
    out_optional() {}

    out_optional(const out_optional&) = delete;
    out_optional& operator =(const out_optional&) = delete;

    void destruct(bool b) { if (b) { reset(b); } }

    void reset(bool& b) { if (b) { reinterpret_cast<T*>(data)->~T(); b = false; } }
    void reset(bool& b, const T& value) { reset(b); new (data) T{value}; b = true; }
    void reset(bool& b, T&& value) { reset(b); new (data) T{value}; b = true; }

    const T* get_ptr(bool b) const { return b ? reinterpret_cast<T*>(data) : nullptr; }
    T* get_ptr(bool b) { return b ? reinterpret_cast<T*>(data) : nullptr; }

    const T& get(bool b) const { assert(b); return *get_ptr(b); }
    T& get(bool b) { assert(b); return *get_ptr(b); }

    // Other stuff as swap, pseudo assignment/move, more constructors

private:
    alignas(T) char data[sizeof(T)];
};

/**
 * 'Tuple' of optional, packaged with bool at the end.
 */
template <typename ... Ts>
struct multi_optional
{
    template <std::size_t I>
    using type = typename std::tuple_element<I, std::tuple<Ts...>>::type;

    static_assert(std::is_same<int, type<0>>::value, "");
public:
    multi_optional() = default;

    ~multi_optional()
    {
        destruct(std::index_sequence_for<Ts...>());
    }

    multi_optional(const multi_optional&) = delete; // To be implemented.
    multi_optional& operator =(const multi_optional&) = delete; // To be implemented.

    template <std::size_t I>
    const auto* get_ptr() const { return std::get<I>(data).get_ptr(flags[I]); }

    template <std::size_t I>
    auto* get_ptr() { return std::get<I>(data).get_ptr(flags[I]); }

    template <std::size_t I>
    const auto& get() const { return std::get<I>(data).get(flags[I]); }

    template <std::size_t I>
    auto& get() { return std::get<I>(data).get(flags[I]); }

    template <std::size_t I>
    void reset() { return std::get<I>(data).reset(flags[I]); }

    template <std::size_t I>
    void reset(const type<I>& value) { return std::get<I>(data).reset(flags[I], value); }


   // Other stuff as copy/move assignment/constructor, ...

private:
    template <std::size_t ... Is>
    void destruct(std::index_sequence<Is...>)
    {
        int dummy[] = { 0, (std::get<Is>(data).destruct(flags[Is]), 0)... };
        static_cast<void>(dummy);
    }

private:
    std::tuple<out_optional<Ts>...> data;
    std::array<bool, sizeof...(Ts)> flags = {{}};
};

Live Demo

关于c++ - 创建一个可选的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30732936/

相关文章:

C++ - 具有 volatile 变量的模板函数 - 无法调用模板特化

c++ - boost::condition_variable::notify_one() 的行为

c# - 在 select 语句中使用命名元组

python - 有没有办法在解包时将 splat-assign 分配为元组而不是列表?

c++ - 如何在编译时根据 constexpr 结果选择函数

c++ - 如何在 C++ 中实现无操作宏(或模板)?

c++ - 编译器怎么知道不从锁定/解锁内部优化语句?在 C++ 中使用 boost::spinlocks

c++ - 如何使用 odeint 的标签系统为各种步进器类型做特定的工作

python - Django - 复杂的嵌套列表和元组解包

c++ - 1>链接 : fatal error LNK1104: cannot open file 'libboost_system-vc90-mt-gd-1_36.lib'