0

I'm trying to implement a class that contains a valarray and 2 ints that define its size. My hpp file looks something like this:

class Matrix
{
public:
    // Constructors
    Matrix();
    Matrix(int width, int height);

    // Mutators
    void setWidth(int width);               // POST: width of the matrix is set
    void setHeight(int height);             // POST: height of the matrix is set
    //void initVA(double width);

    // Accessors
    int getWidth();                         // POST: Returns the number of columns in the matrix
    int getHeight();                        // POST: Returns the number of rows in the matrix

    // Other Methods
    //void printMatrix(const char* lbl, const std::valarray<double>& a);

private:

    int width_;
    int height_;
    std::valarray<double> storage_;
};

However, when I try to initialize the valarray on the constructor like this:

Matrix::Matrix(int width, int height)
{
    width_ = width;
    height_ = height;
    storage_(width*height);
}

I keep getting this error message:

error C2064: term does not evaluate to a function taking 1 arguments

The documentation says that I can declare a valarray in at least 5 different ways, but only the default contructor works. I've looked everywhere but haven't been able to find any useful info. Any help would be appreciated.

Jota
  • 234
  • 2
  • 11
  • 1
    Use the initializer list. What you're trying to do isn't valid because a) invalid syntax b) the member is already initialized at that point. – Luchian Grigore May 08 '13 at 16:22
  • @LuchianGrigore The syntax is actually valid, it just refers to an `operator()` overload that doesn't exist. (And that probably wouldn't do what the OP is wanting if it did exist.) – cdhowie May 08 '13 at 16:26
  • @cdhowie you're right, I was referring to invalid initialization syntax. I can see how I was a bit too brief. – Luchian Grigore May 08 '13 at 16:35

1 Answers1

3

You are actually trying to invoke std::valarray<double>::operator()(int) here, but no such operator exists. Presumably, you meant to use an initializer list instead:

Matrix::Matrix(int width, int height)
    : width_(width),
      height_(height),
      storage_(width*height)
{
}

Alternatively, you can assign a new object instance instead, but this will be less performant than using an initializer list, as storage_ will be default-constructed, and then replaced with a copy of the new temporary, and finally the temporary will be destructed. (A decent compiler may be able to eliminate some of these steps, but I would not rely on that.)

storage_ = std::valarray<double>(width*height);
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • That solved the problem! However, I fail to see the difference. It's been a while since I've used c++ and I've been running into multiple problems. Why does the init. list invoke the "()" operator but not the code that I initally had? – Jota May 08 '13 at 16:26
  • @Oniros The initializer list replaces any default-initialization of object members performed by the compiler. The syntax required for initialization in this list and for assignment outside of the list are entirely different. – cdhowie May 08 '13 at 16:27
  • 1
    @Oniros The code that you initially had *did* try to invoke `operator()`, you have that backwards. The initializer list syntax mimics construction syntax for variables (e.g. `std::valarray foo(5);`). `a(b)` has different meaning in the initializer list and outside of it. In the initializer it means "initialize `a` to `b`", while outside it means "invoke `operator()` on `a`, passing `b`." – cdhowie May 08 '13 at 16:29