Почему я не могу создать и открыть офстрим в одной строке кода? - PullRequest
0 голосов
/ 19 октября 2018

Я могу сделать:

std::ofstream outfile; outfile.open("foo");

, но не:

std::ofstream outfile.open("foo");

, поскольку это дает эту ошибку:

error: expected ';' at end of declaration
    std::ofstream outfile.open("foo");
                         ^

, как вы также можете видеть в Live Demo .

Почему?

PS: я знаю, что могу просто std::ofstream outfile("foo");, но я подозреваю, что мне не хватает механизмаC ++, вот почему я спрашиваю.

Ответы [ 7 ]

0 голосов
/ 19 октября 2018

Я предполагаю, что вы привыкли к чему-то вроде Java или C #, где возможны такие вещи:

BufferedReader br = new BufferedReader(new FileReader(FILENAME));

Или даже Python:

lines = open("filename").readlines();

Трюк здесьв том, что с правильными «фабричными функциями» вы могли бы делать это и в C ++, но это не то, как этот конкретный класс сделанДругие примеры, приведенные выше, с одним из них:

std::ofstream outfile{"foo"};
auto outfile = std::ofstream("foo");

- это «нормальный» способ сделать это в C ++.Часть вашего отсоединения заключается в том, что метод open() возвращает void: std :: basic_ofstream :: open () doc .Поэтому, когда у вас есть этот код:

std::ofstream outfile.open("foo");

Он не компилируется, потому что open() является функцией-членом (не статичной) И возвращает void, а не std::ofstream, что вы и объявилиДелаем.

Надеюсь, это прояснит для вас.

0 голосов
/ 19 октября 2018

Потому что вы не можете.

Серьезно.

C ++ имеет допустимый синтаксис, и вы не должны писать код, который его не придерживается.

Тамэто нулевой вариант использования для объявления / гибридного выражения, использующего void возвращающуюся функцию-член для объекта, который еще не существует, и без = инициализатора.

Но вы уже знали это.

0 голосов
/ 19 октября 2018

Аналогично тому, как если у вас есть функция, которая возвращает объект, и вы хотите вызвать метод для него в той же строке:

struct foo { void bar(){} };
foo create_foo() { return foo(); }

Вы можете сохранить результат create_foo илииспользуйте его возвращаемое значение для вызова метода, но не оба:

create_foo().bar();          // OK
auto f = create_foo();       // OK
auto f = create_foo().bar(); // NOPE

Назад к ofstream: Вы можете написать

std::ofstream().open("foo");

, но у вас не будет шанса получитьссылка на ofstream.

0 голосов
/ 19 октября 2018

Из-за языка.C ++ не допускает такие инструкции.

Используйте конструктор

std::ofstream outfile("foo");

или инициализацию

std::ofstream outfile { "foo" };

0 голосов
/ 19 октября 2018

Вы можете сделать это:

std::ofstream outfile { "foo" };
0 голосов
/ 19 октября 2018

, но не:

std::ofstream outfile.open("foo");

Это простая и простая синтаксическая ошибка.На этом этапе outfile интерпретируется как имя некоторого неопределенного объекта.Компилятор просто не понимает, что вы хотите создать объект типа ofstream.

Мы можем наивно надеяться, что сможем просто исправить это так:

auto outfile = std::ofstream().open("foo"); // call open on a constructed object.

Проблема в том, чточто метод open не возвращает копию ofstream, поэтому это не сработает.(фактически возвращает void).

Вещи, которые будут работать:

// unexciting, but simple - uses a different constructor
std::ofstream outfile{"foo"};

Это (ИМХО) более читабельно, а также законно:

auto outfile = std::ofstream("foo");
0 голосов
/ 19 октября 2018

Почему?

Поскольку язык не позволяет объединять объявление с вызовом функции-члена.Переменная outfile даже не существует до объявления.

Используйте конструктор, чтобы открыть файл:

std::ofstream outfile("foo");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...