Почему компилятор жалуется redefiniton of 'reader' with a different type
когда я пытаюсь передать объект fstream из main () в конструктор другого класса для его чтения? Я знаю, что, может быть, я тупой способ сделать это, мне просто нужно иметь строку в качестве параметра, запрашивающую имя файла, а затем передать ее в поток, который я выделю в конструкторе класса. Но в любом случае мне интересно, почему это не работает, предупреждение компилятора загадочно.
моя основная функция:
fstream reader;
reader.open("read.txt");
Markov(reader);
Конструктор в классе Markov.h:
class Markov {
public:
/** Constructor */
Markov(fstream inStream) {
Map<string, Vector<string> > array0;
char ch;
while (inStream.good())
{
ch = inStream.get();
cout << ch << endl;
}
cout << "End: " << ch;
order0(array0);
}
Линия Markov(reader);
создает переменную под названием reader
типа Markov
, Это эквивалентно следующему: Markov reader;
, Конечно, поскольку компилятор считает, что вы объявляете другую переменную с именем reader
Бросает эту ошибку. Чтобы создать экземпляр Markov
, сделай это:
Markov m(reader);
Это неоднозначность в грамматике C ++, которая всегда воспринимается как объявление переменной, а не как создание временной переменной. На самом деле, вы можете иметь столько скобок, сколько захотите, вокруг имени переменной в вашем объявлении: Markov (((((reader)))))
,
Markov(reader)
конечно, прекрасно синтаксис для создания временного типа Markov
До тех пор, пока это не будет в утверждении, которое может быть проанализировано как объявление. Например, если оно находится в середине выражения, все будет в порядке. В надуманном выражении something += Markov(reader) - 6
, это не может быть интерпретировано как объявление.
Аналогично, если в конструктор передается более одного аргумента, Markov(reader, writer)
или если один аргумент не является идентификатором, Markov("foo")
не совсем однозначно.
Если вы используете компилятор C ++ 11, вы действительно можете создать временный (хотя я не вижу причин для этого), который принимает идентификатор одного аргумента, используя новый синтаксис инициализации:
Markov{reader};
Вы можете передать это fstream
от ссылка.
Markov(fstream& inStream)
И пока вы на это, если вы используете его только для служб ввода, используйте ifstream&
вместо.