Перегрузка двоичного оператора сдвига в первом аргументе

Я хотел бы создать класс файлового потока, который я могу использовать для печати и чтения отформатированных (текстовых) и неформатированных (двоичных) данных. Операторы сдвига (<< и >>) уже существуют, а также пишут и читают члены файловых потоков, но я хотел бы использовать оператор сдвига << только и создать неформатированный вывод, если поток открыт в двоичном режиме и отформатирован иначе.

Код, который я написал, не работает правильно, по крайней мере, для строк и символов (и cstrings):

class mixstream:public fstream {

public:

//some constructors and public functions in the code

template <class T> mixstream& operator<< (T&& param)
{
if (openmode() & ios_base::binary)
write((char *) &param, sizeof(param)); //binary write-out

else
fstream::operator<<(param); //non-binary write out

return *this;
}

template <class T> mixstream& operator>> (T&& param)
{
if (openmode() & ios_base::binary)
read((char *) &param, sizeof(param)); //binary read-in

else
fstream::operator>>param; //non-binary read-in

return *this;
}
};

Проблема, вероятно, где-то рядом оператор сдвига ostream, так что ostream’s << и >> операторы не перегружены символами, последовательностями и строками.

Не могли бы вы указать, где я должен изменить свой код и что заменить на что?

Я также был бы признателен, если бы вы давали советы и демонстрировали хорошую практику для моих целей, поэтому обходные пути также принимаются — если они элегантны.

1

Решение

Основано на еще одном вопросе под названием «Проблема с переопределением оператора<<»В классе, полученном из« ostream »«Я могу достичь своих целей.

  1. Как предложил Йоханнес Шауб-литб по ссылке выше, я не использую оператор сдвига в качестве функции-члена, я буду использовать его в качестве свободных функций. Поэтому я должен определить новый член класса, который хранит, был ли файл открыт в двоичном режиме или нет.
  2. Семантика перемещения кажется необходимой. Без этого выходы string, char и cstring работают некорректно (по крайней мере, работают не так, как ожидалось :)).
  3. Ответ UncleBens с твиками выглядит хорошо.

Сначала определите класс:

class mixstream:public fstream
{
bool binmode;

public:
//constructors
explicit mixstream() {};

explicit mixstream ( const char * filename, ios_base::openmode mode = ios_base::in | ios_base::out) :
fstream(filename, mode)
{
if (mode & ios_base::binary)
binmode = true;

else
binmode = false;

};

void open(const char *_Filename, ios_base::openmode _Mode = ios_base::in | ios_base::out, int _Prot = (int)ios_base::_Openprot)
{
fstream::open (_Filename, _Mode, _Prot);

if (_Mode & ios_base::binary)
binmode = true;

else
binmode = false;

}

bool get_binmode() const {return binmode;}
}

А затем определите перегруженный оператор диссертации и извлечения:

template <class T> mixstream& operator<< (mixstream& stream, const T&& param)
{
if (stream.get_binmode())
stream.write((char *) &param, sizeof(param));

else
(fstream&)stream << param;

return stream;
}

template <class T> mixstream& operator>> (mixstream& stream, const T&& param)
{
if (stream.get_binmode())
read((char *) &param, sizeof(param));

else
ostream::operator>>param;

return *this;
}

Итак, я могу использовать мой новый поток в форме:

int main(int argc, char *argv[]) {

mixstream bin_or_not;
if (true) //some condition
bin_or_not.open("file.dat",ios_base::out | ios_base::binary);

else
bin_or_not.open("file.dat",ios_base::out);char testcs[] = "testsc";
string tests("tests");
int testn = 10;

bin_or_not << 10 << testn << "testcs" << testcs << tests;

return 0;
}

Комментарии и ответы по-прежнему приветствуются в качестве предложений по улучшению.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]