访问命名联合中的字段
Access fields in a named union
我想在以下结构中有一个命名联合,这样我就可以 memcpy
它而不知道什么字段是 "active"。
struct Literal {
enum class Type : size_t {
INT = 1,
LONG,
FLOAT,
DOUBLE
} type;
union {
int li;
long ll;
float lf;
double ld;
} v;
constexpr Literal(int li): type{Type::INT}, v.li{li} {}
constexpr Literal(long ll): type{Type::LONG}, v.ll{ll} {}
constexpr Literal(float lf): type{Type::FLOAT}, v.lf{lf} {}
constexpr Literal(double ld): type{Type::DOUBLE}, v.ld{ld} {}
};
如何初始化构造函数中的字段? v.li{li}
和 li{li}
都不起作用。
我也试过 v{li}
但它只适用于第一个构造函数,因为它将其他 3 个构造函数转换为 int。
编辑:来自@StoryTeller 的回答和评论:
struct Literal {
enum class Type : size_t {
INT = 1,
LONG,
FLOAT,
DOUBLE
} type;
union {
#define UNION_FIELDS int li; long ll; float lf; double ld;
union { UNION_FIELDS } value;
union { UNION_FIELDS };
};
};
您只能在其 c'tors 成员初始化列表中初始化 Literal
的直接成员。由于缩小转换,联合成员的聚合初始化将不起作用。所以你的选择是:
- 命名联合成员类型,并向其添加适当的 c'tors。
递归以强制联合字段被视为 Literal
class 的字段。有一个union of unions,并依赖公共初始序列保证:
union {
union {
int li;
long ll;
float lf;
double ld;
} v;
union {
int li;
long ll;
float lf;
double ld;
};
};
constexpr Literal(int li): type{Type::INT}, li{li} {}
constexpr Literal(long ll): type{Type::LONG}, ll{ll} {}
constexpr Literal(float lf): type{Type::FLOAT}, lf{lf} {}
constexpr Literal(double ld): type{Type::DOUBLE}, ld{ld} {}
以上内容允许您根据匿名联合成员的名称引用每个字段,以及使用命名的 v
成员将它们集中在一起。但我会第一个承认,它很丑。
我想在以下结构中有一个命名联合,这样我就可以 memcpy
它而不知道什么字段是 "active"。
struct Literal {
enum class Type : size_t {
INT = 1,
LONG,
FLOAT,
DOUBLE
} type;
union {
int li;
long ll;
float lf;
double ld;
} v;
constexpr Literal(int li): type{Type::INT}, v.li{li} {}
constexpr Literal(long ll): type{Type::LONG}, v.ll{ll} {}
constexpr Literal(float lf): type{Type::FLOAT}, v.lf{lf} {}
constexpr Literal(double ld): type{Type::DOUBLE}, v.ld{ld} {}
};
如何初始化构造函数中的字段? v.li{li}
和 li{li}
都不起作用。
我也试过 v{li}
但它只适用于第一个构造函数,因为它将其他 3 个构造函数转换为 int。
编辑:来自@StoryTeller 的回答和评论:
struct Literal {
enum class Type : size_t {
INT = 1,
LONG,
FLOAT,
DOUBLE
} type;
union {
#define UNION_FIELDS int li; long ll; float lf; double ld;
union { UNION_FIELDS } value;
union { UNION_FIELDS };
};
};
您只能在其 c'tors 成员初始化列表中初始化 Literal
的直接成员。由于缩小转换,联合成员的聚合初始化将不起作用。所以你的选择是:
- 命名联合成员类型,并向其添加适当的 c'tors。
递归以强制联合字段被视为
Literal
class 的字段。有一个union of unions,并依赖公共初始序列保证:union { union { int li; long ll; float lf; double ld; } v; union { int li; long ll; float lf; double ld; }; }; constexpr Literal(int li): type{Type::INT}, li{li} {} constexpr Literal(long ll): type{Type::LONG}, ll{ll} {} constexpr Literal(float lf): type{Type::FLOAT}, lf{lf} {} constexpr Literal(double ld): type{Type::DOUBLE}, ld{ld} {}
以上内容允许您根据匿名联合成员的名称引用每个字段,以及使用命名的
v
成员将它们集中在一起。但我会第一个承认,它很丑。