C ++:如何从标准布局类模板中优化出一个空的数据成员?

时间:2019-04-23 08:37:05

标签: c++ c++11 templates layout

我可以使用带有可选的非静态数据成员的类模板的标准布局实例吗?如果为“可选”,则表示在模板类的某些实例中必须不存在有问题的数据成员。

也就是说,给出:

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可能是用其他某种语言编写的,或者可能只是用其他编译器构建的。这看起来像是标准布局结构的工作。

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

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

1 个答案:

答案 0 :(得分:3)

如何?

#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;
};