c++ - 模板化结构中的零大小成员变量

标签 c++ templates

我有一个模板化结构,它有一个带有额外 float 的变体,如下所示:

template <bool HasFloat>
struct Foo {
   std::vector<int> a;
   float b; // Not needed if HasFloat is false
};

为了节省内存(是的,这很重要)如果 HasFloat 为假,我想省略该 float 。由于 struct 中还有很多其他内容,最好的方法是这样的:

using B = typename std::conditional<HasFloat, float, ZeroSizedType>::type;
B b;

除了据我所知在 C++ 中没有大小为零的类型。唯一的异常(exception)似乎是“灵活数组成员”,所以我也许可以这样做:

using B = typename std::conditional<HasFloat, float, float[]>::type;

除了它们仅在 C99 中受支持,在 C++ 中不受支持。

这个问题的标准解决方案似乎是使用继承,因为基类可以是零大小的,但是我的结构也可以被程序集访问,为了使程序集更简单,最好是float b; 位于结构的末尾而不是开头,无论如何 that isn't guaranteed .

所以这似乎将模板特化作为唯一的选择,但我的类(class)实际上相当长,我想避免重复所有内容。我还缺少其他解决方案吗?

最佳答案

我的一位同事想出了一个相当不错的解决方案。它确实需要复制和粘贴数据成员,但至少我不必复制我的方法。

template <bool HasFloat>
struct Foo {
  struct State {
    std::vector<int> a;
  };

  struct StateWithFloat {
    std::vector<int> a;
    float k;
  };

  using FooState = std::conditional_t<HasFloat, StateWithFloat, State>;
  FooState state;
};

你可以这样做:

  struct StateWithFloat {
    State state;
    float k;
  };

但随后您必须添加模板函数以避免 state.astate.state.a 问题,此时复制和粘贴似乎更容易。

@aschepler 还指出,在 C++20 中,您将能够使用 [[no_unique_address]] .

关于c++ - 模板化结构中的零大小成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52704116/

相关文章:

c++ - 使用 gdb 调试在问号函数 "?? ()"中显示段错误

c++ - 使用可变参数模板构建元组

python - 如何使用 Django 模板应用外部 URL

c++ - initializer_list 和 move 语义

c++ - 'deep' 模板参数推导是否可行?

c++ - 重载组合运算符(+ =,-=,* =和/=)。不计算应如何

c++ - 类前向声明​​失败

c++ - 如何编写将自身作为回调传递的匿名函数/lambda?

c++ - 获取错误 C++ 即使拥有所有构造函数也没有匹配的调用函数

c++ - 如何从模板访问模板类的静态?