我有一个模板化结构,它有一个带有额外 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.a
与 state.state.a
问题,此时复制和粘贴似乎更容易。
@aschepler 还指出,在 C++20 中,您将能够使用 [[no_unique_address]]
.
关于c++ - 模板化结构中的零大小成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52704116/