Reputation: 2002
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);
}
Upvotes: 0
Views: 92
Reputation: 110758
The line Markov(reader);
is creating a variable called reader
of type Markov
. It is equivalent to the following: Markov reader;
. Of course, since the compiler thinks you're declaring another variable called reader
, it throws up this error. To create an instance of Markov
, do this:
Markov m(reader);
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 type Markov
, 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 expression something += 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:
Markov{reader};
Upvotes: 4
Reputation: 66254
You may want to pass that fstream
by reference.
Markov(fstream& inStream)
And while you're at it, if you're only using it for input services, use an ifstream&
instead.
Upvotes: 2