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