Я рефакторинг некоторого устаревшего кода, который считывает некоторые двоичные данные из файла в struct. Мне пришло в голову, что изменение переменной на std :: option может гарантировать, что переменная действительно прочитана (инициализирована) перед ее использованием. Но код чтения файла требует адрес переменной. Есть ли способ (предполагаемый способ не взломать), чтобы сказать std :: option "дать мне указатель на ваш неинициализированный T, чтобы я мог записать содержимое этой памяти" и "go вперед и измените ваше состояние с пустого на полноценное сейчас "?
(то есть вместо назначения значения по умолчанию 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));
Вы, возможно, ранее возражали, что функция, принимающая адрес неинициализированного T в std :: option и устанавливающая необязательную, так как больше не пустая, рискует случайно оставляя необязательное помеченное значение-ful, оставаясь при этом неинициализированным, если пользователь фактически не записывает память. Однако обратите внимание, что приведенный выше пример кода представляет собой аналогичный, хотя и меньший риск: если сгенерирует reader-> read (), необязательный больше не будет пустым, но он также недопустим для использования. Созданный по умолчанию T, вероятно, лучше, чем неинициализированный T, однако, если FILE_HEADER является C структурой (что в данном случае таковым является), его члены все еще неинициализированы!
Возможно, это лучше:
FILE_HEADER temp;
reader->read(&temp, sizeof(FILE_HEADER));
fileHead = temp;
Но оба они включают избыточную инициализацию и / или копирование (возможно, оптимизированное компилятором).