C++ 初始化结构中的并集-c++;

C++ 初始化结构中的并集-c++;,c++,C++,我的代码: #include <iostream> using namespace std; struct widget { char brand[20]; int type; union id { long id_num; char id_char[20]; }id_val; }; int main() { widget prize = {"Rolls", 0, "A2X"};

我的代码:

#include <iostream>

using namespace std;

struct widget
{
    char brand[20];
    int type;
    union id
    {
        long id_num;
        char id_char[20];
    }id_val;
};

int main()
{
    widget prize = 
    {"Rolls", 0, "A2X"};

    return 0;
}
#包括
使用名称空间std;
结构小部件
{
char品牌[20];
int型;
工会id
{
长id_num;
char id_char[20];
}身份证;
};
int main()
{
小部件奖=
{“滚动”,0,“A2X”};
返回0;
}
问题在于初始化结构中的联合时初始化“A2X”。当我传递“A2X”时,编译器不知道我想选择第二个选项和字符数组,它需要长类型。当我把

字符id_char[20]

以前

长id_num

一切都好。但我想知道如何强制编译器接受“A2X”,并将char作为union中的第二个选项。谢谢你的帮助

但我想知道如何强制编译器接受“A2X”,并将char作为union中的第二个选项

您可以使用构造函数:

id(char const *id_char) {
    std::strcpy(this->id_char, id_char);
}
或者,您可以使用
小部件
构造函数


一个缺点是,如果您使用过大的输入字符串进行初始化,编译器可能无法向您发出警告。可以使用
strlen
扩展所示的平凡构造函数,以在运行时检查溢出。如果选择检查,我建议抛出异常。

这适用于
-std=c++11

#include <cstring>
#include <stdexcept>

struct widget
{
    char brand[20];
    int type;
    union id
    {
        long id_num;
        char id_char[20];
    }id_val;
    widget(char const*Str, int Type, char const *Id);
};

widget::widget(char const*Str, int Type, char const *Id) 
{
    if (strlen(Str)+1 > sizeof brand)
        throw std::length_error{"brand too large"};
    memcpy(brand,Str,strlen(Str)+1);
    type = Type;
    if (strlen(Id)+1 > sizeof id_val.id_char)
        throw std::length_error{"id too large"};
    memcpy(id_val.id_char,Id,strlen(Id)+1);

}

int main()
{
    widget prize = {"Rolls", 0, "A2X"};

    return 0;
}
#包括
#包括
结构小部件
{
char品牌[20];
int型;
工会id
{
长id_num;
char id_char[20];
}身份证;
小部件(字符常量*Str,int类型,字符常量*Id);
};
widget::widget(字符常量*Str,int类型,字符常量*Id)
{
如果(strlen(Str)+1>品牌大小)
抛出std::length_错误{“品牌太大”};
memcpy(品牌、Str、strlen(Str)+1);
类型=类型;
if(strlen(Id)+1>Id的大小
抛出std::length_错误{“id太大”};
memcpy(id_val.id_char,id,strlen(id)+1);
}
int main()
{
widget prize={“Rolls”,0,“A2X”};
返回0;
}

为什么不定义widget::widget(char*,long,char*)形式的构造函数?可能重复?我目前正在阅读Cpp primer plus,这是本书中的示例,因此我想知道如何在没有此类内容的情况下解决它,在本示例之前没有涉及到这些内容。我在寻找最简单的解决方案。我不明白你们在这里想要实现什么。Union为它的所有成员定义了相同的值,在这里您有完全不同的类型,它们应该具有相同的值。Union不是简单的
strncpy
在这里是一个糟糕的选择,因为如果源太多,它将使字符串以非null结尾long@M.M我明白了。检查memcpy它是。注意,在引用文本初始值设定项的情况下,可以使用模板构造函数,并在编译时检查长度。如果传入变量,则在运行时之前无法检查长度,但最好通过截断来限制输入大小,而不是使程序崩溃。@BenVoigt模板构造函数的优点是,这是一个值得选择的选项。运行时截断确实也是一种选择,但我不同意它是一种更好的选择。请注意,我并没有建议程序崩溃,只是简单地抛出一个异常。这不会终止程序,除非您忘记捕获和处理案例。如果处理时间受限的系统,无校验方法也很有用。只要类/联合的用户遵循记录的前提条件,就不需要在运行时进行检查。不过,我会在实际的word实现中添加一个断言。