如何区分 POD 和非 POD?
How to distinguish PODs and non PODs?
我有一个文件处理程序,可以读取和写入自定义二进制文件。为了节省自己的工作,我从一个基本结构(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
的实例",这样你至少知道它是这样(不要忘记这个标头仍然可以在任意数据中找到纯粹偶然(。但是您还需要将该逻辑构建到序列化阶段(在出局时(。
- 如何将模板和非模板函数放在一个文件中
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 一个模板方法,用于同时接受常量和非常量参数
- C++ 常量正确性/缺少支持常量和非常量实例的类的常量构造函数
- C++,如何使用常量对象和非常量对象进行比较?
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 避免易失性和非易失性成员函数的代码重复
- 修改和非修改 putback() 之间的区别
- GCC 和非命名空间范围内的显式专用化
- 常量和非常量 getter 具有相同的名称
- ADL 和非类型模板参数
- 处理一般情况混合类型和非类型的可变参数模板
- C++模板和非模板函数之间的重载解析
- 如何在单个模板调用中传递const_iterator和非const迭代器
- 获取模板以匹配常量 T* 和非常量 T* 的不同序列
- 如何区分 POD 和非 POD?
- POD和非POD类之间的性能差异
- 运算符新[]和非POD类型
- 向包含POD和非POD成员的现有结构添加移动语义
- 如何在常量和非常量上下文中使用相同的 POD