如何区分 POD 和非 POD?

How to distinguish PODs and non PODs?

本文关键字:POD 和非 何区      更新时间:2023-10-16

我有一个文件处理程序,可以读取和写入自定义二进制文件。为了节省自己的工作,我从一个基本结构(base_p(继承了多个数据:

struct base_p{
protected:
uint32_t v0= 0;
uint32_t v1= 0;
uint32_t v2= 0;
friend struct f_block;
// other friends
};

现在,在构建该文件的内部块时,我将该结构继承为多个非 POD 类型:

struct f_block:public base_p{
f_block(){
this->v0 = 0x3f580058; // an magic number of the block
this->v1 = 0x1000004D; // version and use type
this->v2 = 0;
}
f_block(uint32_t data){
this->v0 = 0x3f580058; // an magic number of the block
this->v1 = 0x1000004D; // version and usage type
this->v2 = data;
}
operator uint8_t(){ return this->v1 & 0xff; }
operator bool(){return this->v2 != 0 ;}
friend std::ostream& operator<<( std::ostream& os, f_block& fb );
};
std::ostream& operator<<( std::ostream& os, f_block& fb ){
union {
uint32_t vrt;
unsigned char parts[4];
}temp;
temp. vrt = fb. v2;
return os << temp. parts[3] << temp. parts[2] << temp. parts[1] << temp. parts[0];
}

在我的文件处理程序中,我可以使用这两种结构。例如,如果我需要在某处传递数据,我需要将数据提取为base_p。但是我的块定义有一个额外的功能,usage服务和压缩键,并且在data(v2(中,我还存储了一些信息,例如从末尾的位偏移量,特色块的长度......等等。因此,提取函数看起来如下:

struct file_handler{
std::vector<base_p> data;
file_handler():data(0){}
virtual bool read(const char *filename) = 0; // to be overridden
virtual bool write(const char *filename)= 0; // to be overridden  
virtual bool set( base_p &data){
// if data is base_p , push_back data as normal POD  
// if data is f_block, push_back data as deflated version  
// don't store anything in vector if none
}
virtual bool get( base_p &data){
// if data is base_p, returns lasts 3 elements v2(data) fields
// if data is f_block, returns last element as f_block - inflated, 
// set data as 0 if none
}
}

我试图捕获调用base_p中不存在的函数的错误,但这不适合我,因为我正在file_handler应该接受其他数据类型的结构上构建多个文件处理程序。一旦我能够成功实现file_handler,我就足够安全,可以开始构建其他文件类型。我需要的是数据类型切换语句的内容。

由于我来自python背景,我可以在其中做一些类似isinstance或类似的事情。但这很C++所以没有这样的实现 -我知道

我搜索过,

发现一些元素似乎有可能解决我的问题,但其中大多数是过时的版本,或者太抽象了,无法让我的头脑产生逻辑解决方案。

SFINAE
  • 和 void :提到了 SFINAE 遵循的某种概念,以及复合概念,这些概念对我来说太抽象了,无法成功实现。
  • HasMember SFINAE :这对于构造函数识别似乎是可行的,但最好的答案是用c++03写的,如果它翻译成我目前正在使用的c++11又名版本,则没有提及。

有没有办法区分 POD 和非 POD ?

我来自python背景

C++不是Python。

如果你所拥有的只是一个void*,不知道它来自哪里或它指向什么对象,那么你就无能为力。 C++是一种静态类型的语言。这意味着对象不会自动在自身中存储任何将它们标识为特定类型的内容。所有这些类型信息都是在编译时根据编译器在代码中看到的类型完成的。

这里出现的类型是void,即"非类型"类型。因此,所有键入信息都已丢失。并且无法通过查看void*后面的一些字节来恢复它。

就该void*后面的第一个字节的内容而言,指向subs的指针和指向my_data的指针之间没有区别

听起来您希望能够获取任意字节块,并确定这些字节是否构成类型my_data实例的基础表示形式。

你不能。没有这样的事情是有意义的。这些字节没有类型

您必须使用您设计的规则手动反序列化字节,选择其中的值(如果如此解释(是否与my_data对象中值的前提条件匹配。

通常我们会用一些"标头"自己管理数据,指示"这是一个my_type的实例",这样你至少知道它是这样(不要忘记这个标头仍然可以在任意数据中找到纯粹偶然(。但是您还需要将该逻辑构建到序列化阶段(在出局时(。