Tom Lilletveit
Tom Lilletveit

Reputation: 2002

C++ redefiniton of 'name' with a different type compiler warning

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

Answers (2)

Joseph Mansfield
Joseph Mansfield

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

WhozCraig
WhozCraig

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

Related Questions