首页 > 解决方案 > C++:如何优化标准布局类模板中的空数据成员?

问题描述

我可以有一个带有可选非静态数据成员的类模板的标准布局实例吗?“可选”意味着相关数据成员不得出现在模板类的某些实例中。

也就是说,给定:

template <typename T>
struct Dependent
{
    T      m_defaultValue;
};

template <>
struct Dependent<double>
{
};

template <typename T>
struct MyData
{
    T*              m_data;
    Dependent<T>    m_optional;

    T LotsOfAccessorMethods() const;
};

我希望的布局MyData<int>等同于struct { int* x; int y; }.

我希望的布局MyData<double>相当于struct { double* x; }.

这里的问题是解决方案必须遵守以下关键限制:

  1. MyData<> 必须满足标准布局类的要求。这意味着所有数据成员都应该位于一个类中。将可选数据成员重构为基类是不可能的。

  2. MyData<> 不能是专门的,甚至不能是部分的。在实际任务中,它有相当多的方法和领域,在所有专业中重复它们会破坏拥有通用模板的全部意义。


背景:

我希望将许多特殊的容器结构传达给我无法控制的 DLL/SO。后者意味着我应该假设 DLL 可能是用其他语言编写的,或者可能只是用其他编译器构建的。这看起来像是标准布局结构的工作。

这些容器结构具有非常相似的数据成员和成员函数集,因此不将它们全部合并到类模板将是一种耻辱(也是维护的噩梦)。

但是,其中一些容器必须具有额外的数据成员(标签 ID、特殊值等)。因此问题。

标签: c++c++11templateslayout

解决方案


这个怎么样:

#include <type_traits>
template <typename T>
struct MyData {
    struct general_impl { T* m_data; T optional; };
    struct double_impl  { T* m_data; };

    using data_type = typename std::conditional<
        std::is_same<T, double>::value,
        double_impl,
        general_impl>::type;

    data_type data;

    T LotsOfAccessorMethods() const;
};

推荐阅读