简体   繁体   中英

Initialize a 2D vector inside constructor of class

I want to initialize a 2D array in the constructor of a class but the compiler gives me this error "call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type".

class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a(x, vector<int>(y , 0 )); }
private:
    vector<vector<int>> a; 


};

Firstly, as mentioned, this:

Matrix(size_t x, size_t y)
{
   a(x, vector<int>(y , 0 ));
}

is not how you initialise a member. To initialise a member, we use the member initializer list , like so:

Matrix(size_t x, size_t y)
   : a(x, vector<int>(y , 0 ))
{}

The colonic syntax is a specific place for listing initialisations. Nothing in the constructor body is an initialisation. When you don't put an initialiser for a member, it is default-initialised. Then the code in your constructor's body is run. As we know, the body of a function consists of statements that are executed.

Now, when you perform the statement <name>(<thing>, <other thing>) , that is a function call. If <name> is not a function but a class instance, then the function call operator operator() is looked up instead. If there isn't one (or it doesn't match the arguments), then compilation fails in the way that you've observed.

Could the language have been designed so that any mention of a member, inside the constructor body, in this form, were treated as an initialisation? Probably. But why? Now you'd have no unambiguous way to perform function-calls instead, and the order in which things happen during construction would be unclear. It's much better the way it is now.

正确的语法是使用初始化列表:

Matrix(size_t x, size_t y) :a(x, vector<int>(y , 0 )) { }

When the control is passed to the body of the constructor then the vector is already created.

So this statement

a(x, vector<int>(y , 0 ));

is not a call of a vector constructor. The vector was already created using the default constructor and the statement above is invalid.

You could use a mem-initializer list in the constructor

class Matrix
{
public:
    Matrix() {};
    Matrix(size_t x, size_t y) : a(x, vector<int>(y ) ) {}
private:
    vector<vector<int>> a; 
};

Or you could use the member function assign in the body of the constructor

class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a.assign (x, vector<int>(y ) ); }
private:
    vector<vector<int>> a; 
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM