Multidimesional vector constructor question

Jul 10, 2015 at 3:11pm
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 Jul 10, 2015 at 3:12pm
Jul 10, 2015 at 3:19pm
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.
Jul 10, 2015 at 3:35pm
Well I still don't understand. They don't do the exact same thing?
Jul 10, 2015 at 3:43pm
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 Jul 10, 2015 at 3:43pm
Jul 10, 2015 at 3:50pm
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);
}
Jul 10, 2015 at 3:54pm
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.
Jul 10, 2015 at 4:01pm
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;
}
Jul 10, 2015 at 4:13pm
First one: m_i is default initialized, then it is assigned i in constructor body.
Second: m_i is initialized with value i.
Jul 10, 2015 at 4:15pm
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 Jul 10, 2015 at 4:15pm
Jul 10, 2015 at 4:25pm
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.