我正在重构一些旧代码,该代码将从文件中读取一些二进制数据到struct中。在我看来,将变量更改为std :: optional可以确保在使用变量之前实际读取(初始化)该变量。但是文件读取代码需要变量的地址。有没有办法(一种既定的方式,不是hack的方式)告诉std :: optional“给我一个指向您的uninitialized T的指针,以便我可以写该内存的内容”和“继续并更改您的状态从无到有,现在变得有价值”?
(即,不分配默认T(如果T没有默认构造函数,然后获取默认构造值的地址。)
简化示例:
struct FILE_HEADER { /* some data members... */ };
class FileFrobulator
{
private:
FILE_HEADER fileHead;
public:
void called_first(IFileReader* reader)
{
// ...
reader->read(&fileHead, sizeof(FILE_HEADER));
// ...
}
void called_later(IFileReader* reader)
{
// ...
// use fileHead.foo, fileHead.bar, etc. while reading rest of file
// ...
}
};
问题是,如果我将成员更改为std::optional<FILE_HEADER> fileHead;
,那么对于当前显示为reader->read(&fileHead, sizeof(FILE_HEADER));
的行,该如何更改?
我可以这样做:
fileHead = FILE_HEADER();
reader->read(&*fileHead, sizeof(FILE_HEADER));
[您可能早些时候曾反对过这样的功能,即在std :: optional中采用未初始化T的地址并将其设置为不再为空的功能,如果用户仍然未初始化,则可能会意外留下可选的已标记值有效的风险实际上不写内存。但是请注意,上面的代码示例运行时也有类似的风险,尽管风险较小:如果reader-> read()抛出,则可选选项将不再为空,但也无效。默认构造的T可以说比未初始化的T更好,但是如果FILE_HEADER是C结构(在这种情况下是C结构),它的成员仍然是未初始化的!
也许这样更好:
FILE_HEADER temp;
reader->read(&temp, sizeof(FILE_HEADER));
fileHead = temp;
但是这两个都涉及冗余的初始化和/或复制(可能由编译器优化)。>>
我正在重构一些旧代码,该代码将从文件中读取一些二进制数据到struct中。在我看来,将变量更改为std :: optional可以确保变量实际读取(...
是否有一种方法(一种既定的方式,不是一种破解)来告诉std :: optional“给我一个指向您未初始化的T的指针,以便我可以写该内存的内容”和“继续进行,将您的状态从空变为现在就有价值”?