c++streamnamed-constructor

Problem with named constructor with istream as argument


I'm trying to create a named constructor for my class Matrix, with an input as a stream from which I can read the values for the initialization.

#include <istream>
// ...

class Matrix
{
public:
    Matrix(int);
    // some methods
    static Matrix *newFromStream(istream&);

private:
    int n;
    std::valarray< Cell > data;
};

The method should be implemented more or less like this

Matrix *Matrix::newFromStream(istream &ist) {

    // read first line and determine how many numbers there are
    string s;
    getline( ist, s );
    ...
    istringstream iss( s, istringstream::in);

    int n = 0, k = 0;
    while ( iss >> k)
        n++;
    Matrix *m = new Matrix( n );    

    // read some more values from ist and initialize        

    return m;
}

However, while compiling, I get an error in the declaration of the method (line 74 is where the prototype is defined, and 107 where the implementation starts)

hitori.h:74: error: expected ‘;’ before ‘(’ token
hitori.cpp:107: error: no ‘Matrix* Matrix::newFromStream(std::istream&)’ member function declared in class ‘Matrix’

These errors, however, I do not get when defining and implementing a named constructor with a simple parameter, like an int.

What am I missing? Any help would be greatly appreciated.


Solution

  • istream is in the namespace std:

    static Matrix *newFromStream(std::istream&);
    

    The error indicates it's lost once it gets to istream. Change it in both header and source, of course. A couple notes:

    In your header, use <iosfwd> instead of <istream>, and in your source file use <istream>. This is more "correct" and may speed up compilation.

    Also, do you really want to return newly allocated memory? This is risky and isn't terribly safe. Stack-allocation would be much easier, and maybe even faster.

    Lastly, just something to keep in mind: You're very close to having a good operator<<. You can implement it in terms of your current function:

    std::istream& operator<<(std::istream& pStream, Matrix& pResult)
    {
        // ... book keeping for istream
    
        pResult = Matrix::from_stream(pStream);
    
        // ... more book keeping
    }