Why do the compiler complain redefiniton of 'reader' with a different type when I try to pass an fstream object from main() into another class´s constructor for it to be read? I am aware of this is maybe i dumb way of doing it, I should really just have a string as parameter asking for filename then pass that into the fstream that I allocate in the constructor of the class. But anyways I am wondering why this don´t work, the compiler warning is cryptic.
my main function:
fstream reader;
reader.open("read.txt");
Markov(reader);
Constructor in Markov.h class:
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);
}
The line
Markov(reader);is creating a variable calledreaderof typeMarkov. It is equivalent to the following:Markov reader;. Of course, since the compiler thinks you’re declaring another variable calledreader, it throws up this error. To create an instance ofMarkov, do this:This is an ambiguity in the grammar of C++ that is always taken as a declaration of a variable, rather than the construction of a temporary. In fact, you can have as many parentheses as you like around the variable name in your declaration:
Markov (((((reader))))).Markov(reader)is of course perfectly fine syntax for creating a temporary of typeMarkov, as long as it isn’t in a statement that could be parsed as a declaration. For example, if it’s in the middle of an expression, you’ll be okay. In the contrived expressionsomething += Markov(reader) - 6, it can’t be interpreted as a declaration.Likewise, if there is more than one argument being passed to the constructor,
Markov(reader, writer), or if the single argument is not an identifier,Markov("foo"), it is not ambiguous.If you’re using a C++11 compiler, you can indeed create a temporary (although I see no reason to do it) that takes a single argument identifier using the new initialization syntax: