Multidimesional vector constructor question

Why doe this work and the next one cause an error?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 #include <vector>
#include <iostream>

using namespace std;

class foo{
public:
	vector<vector<int>> m_bar;
	foo();
};
foo::foo() : m_bar(10, vector <int>(10)){}



int main(){

	foo a;
	a.m_bar[1][1] = 20;
	cout << a.m_bar[1][1] << endl;
	return 0;
}


Below causes an error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
#include <iostream>

using namespace std;

class foo{
public:
	vector<vector<int>> m_bar;
	foo();
};
foo::foo(){

	m_bar(10, vector <int>(10));
}


int main(){

	foo a;
	a.m_bar[1][1] = 20;
	cout << a.m_bar[1][1] << endl;
	return 0;
}
Last edited on
because line 13 tries to call the constructor explicitly, which isn't allowed.

line 11 of the first example has it in the initializer list, so thats ok.
Well I still don't understand. They don't do the exact same thing?
because line 13 tries to call the constructor explicitly, which isn't allowed.
It actually tries to call operator(int, vector<int>). Which vector lacks. Hence error.

It is not like you are not allowed to call constructor. You literally cannot call constructor, as it has no name.
Last edited on
How does the case that works, differ?

I assumed

foo::foo(int i) : m_i(i){}

was equivalent to:

1
2
3
foo::foo(int i){
   m_i(i);
}
First one is initialization. It is a way to provide your own initialization routine instead of relying on them being default-initialized (as some types do not have default constructors or they are costly)

After you enter constructor body, all member variables are initialized. It is impossible to initialize variable second time. Now you can properly use it: call member function, access fields, etc.
Your second example calls operator()(int) on m_i. If m_i does not have one, it is a compiler error.
I think I'm starting to understand.

What happens in each of these constructors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <vector>
#include <iostream>

using namespace std;

class foo{
public:
	int m_i;
	foo(int);
};
foo::foo(int i){
	m_i = i;
}

int main(){

	foo a(1);
	return 0;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <vector>
#include <iostream>

using namespace std;

class foo{
public:
	int m_i;
	foo(int);
};

foo::foo(int i) :m_i(i){}


int main(){

	foo a(1);
	return 0;
}
First one: m_i is default initialized, then it is assigned i in constructor body.
Second: m_i is initialized with value i.
If I understand right, in the second constructor in the post above, the parenthesis represent an early initialization. The parenthesis inside the constructor represent an operator? Something totally different is going on?
Last edited on
in the second constructor in the post above, the parenthesis represent an early initialization
It just initialization. Not early, it happens exactly when standard requires it: before the body of constructor. As you might want or even need to initialize members in specific ways, there is member initialization list — to provide your own initialization for members.

In the body of constructor members are already initialized. There is no special handling like there is for declaration statement: for declaration stuff like
1
2
3
foo bar = baz;
foo bar(baz);
foo bar {baz};
all means initialize bar with baz (with some differences).

In normal variable handling, bar = baz is assigment, bar(baz) invokes function call operator, and bar{baz} makes no sense.

Another example:
1
2
int i(10); //Works fine: initialization
i(10); //Error, normal handling, there is no operator()(int) 
Topic archived. No new replies allowed.