Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重新解释演员阵容是否安全<;常量字符*>;任何以char[size]成员开头的结构?_C++_Undefined Behavior_Reinterpret Cast - Fatal编程技术网

C++ 重新解释演员阵容是否安全<;常量字符*>;任何以char[size]成员开头的结构?

C++ 重新解释演员阵容是否安全<;常量字符*>;任何以char[size]成员开头的结构?,c++,undefined-behavior,reinterpret-cast,C++,Undefined Behavior,Reinterpret Cast,假设我有两个不同的结构: struct A { char a_name[512]; ... // A struct data } struct B { char b_name[256]; ... // B struct data } 给定std::string name,我需要检查容器中是否存在对象(无论是A还是B)。由于A和B都以char[size]成员开始,这是我要比较的名称,因此我尝试了以下方法: //

假设我有两个不同的结构:

struct A {
    char a_name[512];
    ...              // A struct data
}

struct B {
    char b_name[256];
    ...              // B struct data
}
给定
std::string name
,我需要检查容器中是否存在对象(无论是
A
还是
B
)。由于
A
B
都以
char[size]
成员开始,这是我要比较的名称,因此我尝试了以下方法:

// T is a template parameter which is always an object of type A or B
           ↓ 
for (const T& item : container)
    if (name == reinterpret_cast<const char*>(&item))
//T是一个模板参数,它始终是a或B类型的对象
↓ 
用于(常数T和项目:容器)
如果(名称==重新解释铸件(&item))
它确实像预期的那样工作。我读取对象时,就好像它是一个字符数组,但由于
A.A_name
B.B_name
保证以null结尾,我不会读取我不应该读取的内容。。。还是我?上面的代码会产生未定义的行为吗?它会产生我没有考虑的任何错误吗?如果是这样,我该如何完成这项任务


我无法修改
A
B
。我选择不为每个类重载运算符==是因为
A
B
实际上是更多不同的结构,它们具有我上面描述的结构(
char[size]
+更多的数据)。

如果您的类是标准布局类,那么您的代码应该是安全的

在[class.members]一节的末尾,我们有

如果标准布局类对象具有任何非静态数据成员,则如果该成员不是位字段,则其地址与第一个非静态数据成员的地址相同。。。[注意:对象及其第一个子对象是指针可相互转换的]

关于复合类型的部分,[basic.component]说

如果两个对象是指针可相互转换的,则它们具有相同的地址,并且可以通过重新解释转换从指向另一个对象的指针获取指向其中一个对象的指针

但是,您可以通过创建一个helper函数来返回正确的字段,从而完全摆脱
重新解释\u cast

const char *GetName(const A &a) {
    return a.a_name;
}

const char *GetName(const B &b) {
    return b.b_name;
}
// ...
for (const T& item : container)
    if (name == GetName(item))

这方面有很多变化,包括
GetName
开始一个返回特定字段的模板函数,对于具有不同字段名的类型有特定的实现。

什么是
T
?看起来A和B没有共同的基类,因此不可能有
T
?重新打开问题,因为复制显然是错误的。它指向了一个问题,该问题询问了
如何重新解释非char*类型的cast
ing,这就产生了很大的不同??为什么呢您正在处理的实际容器的类型是什么?@chrisdd
T
表示模板函数的类型,而不是父类或其他类型。A和B除了有它的第一个成员
char[]
@SergeyA谢谢你重新打开它,我被搞糊涂了。^^”。容器是一个
std::vector
,而T是一个模板参数。如果这让它更清楚,我可以提供更多的代码