Vector dwuwymiarowy, Iterator.

0

W przypadku vectora jednowymiarowego, mogę odwoływać się do jego elementów za pomocą iteratora:

vector<unique_ptr<CStudent>>::iterator itr;  
	for (itr = CStudent::_students.begin(); itr != CStudent::_students.end(); itr++)
	{
		cout << endl << "Student nr: " << c << endl;
		cout << **itr;
		c++;
	}

Tymczasem, tworzę vector dwuwymiarowy (czy poprawnie?):

vector < vector <unique_ptr<CComplex>>> _M;
fstream M_file(file_name, ios::in);
	if (M_file)
	{
		double real, imaginary;
		for (int i = 0; i < _rozmiarK; i++)
		{
			vector <unique_ptr<CComplex>> xM;
			for (int j = 0; j < _rozmiarW; j++)
			{
				M_file >> real >> imaginary;
				xM.push_back(unique_ptr<CComplex>(new CComplex(real, imaginary)));
			}
			_M.push_back(xM);
			xM.clear();
		}

		M_file.close();
	}

W jaki sposób mogę teraz odwoływać się do elementów za pomocą iteratora/iteratorow?

1
  1. Google nie boli (polecam 0.3 z mojego kursu. Link znajdziesz w stopce)
    https://www.google.nl/search?q=iteracotr+vector+vector+c%2B%2B&oq=iteracotr+vector+vector+c%2B%2B&aqs=chrome..69i57.4679j0j1&sourceid=chrome&ie=UTF-8#q=iterator+vector+2d+c%2B%2B

http://stackoverflow.com/questions/1784573/iterator-for-2d-vector

vector< vector<int> > vvi;
vector< vector<int> >::iterator row;
vector<int>::iterator col;
for (row = vvi.begin(); row != vvi.end(); row++) {
    for (col = row->begin(); col != row->end(); col++) {
        // do stuff ...
    }
} 
  1. zapoznaj sie z auto
0

@fasadin, @JeloneK - a Wy nie robicie czasami wszyscy błędu z iteratorami? Powinno się im robić ++it zamiast it++. Albo czegoś nie wiem o C++ hehe. O_o

2

Dobrym przyzwyczajeniem jest zawsze używać preinkrementacji jeśli to możliwe (t.j. jeśli nie potrzebujesz starej wartości), nawet jeśli w dużej większości przypadków kompilator będzie w stanie wygenerować identyczny kod dla v++ i ++v.

0
grzesiek51114 napisał(a):

a Wy nie robicie czasami wszyscy błędu z iteratorami? Powinno się im robić ++it zamiast it++. Albo czegoś nie wiem o C++ hehe.

Bez znaczenia dla wyniku. Może mieć (nieistotne) znaczenie dla wydajności.


Przykład 1: ```cpp #include <vector> #include <iostream>

using namespace std;

int main()
{
vector<int> w = {1,2,3,4,5,6,7,8,9,10};

for (auto it = w.begin(); it!=w.end(); it++)
	cout << *it;

}

Kod wygenerowany przez Visual C++ 2015 (wyciąłem wypełnianie wektora i sprzątanie na końcu:
```asm
	mov	ebx, DWORD PTR _w$[esp+76]
	xor	ecx, ecx
	mov	ebp, DWORD PTR _w$[esp+80]
	xor	edi, edi
	sub	ebp, ebx
	mov	esi, ebx
	add	ebp, 3
	shr	ebp, 2
	cmp	ebx, DWORD PTR _w$[esp+80]
	cmova	ebp, ecx
	test	ebp, ebp
	je	SHORT $LN3@main
	npad	1
$LL4@main:
	push	DWORD PTR [esi]
	mov	ecx, OFFSET std::cout
	call	std::basic_ostream<char,std::char_traits<char> >::operator<<
	inc	edi
	lea	esi, DWORD PTR [esi+4]
	cmp	edi, ebp
	jne	SHORT $LL4@main
$LN3@main:

Przykład 2: ```cpp #include <vector> #include <iostream>

using namespace std;

int main()
{
vector<int> w = {1,2,3,4,5,6,7,8,9,10};

for (auto it = w.begin(); it!=w.end(); ++it)
	cout << *it;

}


```asm
	mov	ebx, DWORD PTR _w$[esp+76]
	xor	ecx, ecx
	mov	ebp, DWORD PTR _w$[esp+80]
	xor	edi, edi
	sub	ebp, ebx
	mov	esi, ebx
	add	ebp, 3
	shr	ebp, 2
	cmp	ebx, DWORD PTR _w$[esp+80]
	cmova	ebp, ecx
	test	ebp, ebp
	je	SHORT $LN3@main
	npad	1
$LL4@main:
	push	DWORD PTR [esi]
	mov	ecx, OFFSET std::cout
	call	std::basic_ostream<char,std::char_traits<char> >::operator<<
	inc	edi
	lea	esi, DWORD PTR [esi+4]
	cmp	edi, ebp
	jne	SHORT $LL4@main
$LN3@main:

Znajdź 10 różnic.

0

Zamień to: http://4programmers.net/Forum/C_i_C++/269631-lista_list?p=1244148#id1244148 na vector i powinno pójść bez problemu.

0
xM.clear(); // nick nie robi, bo i tak co iterację tworzysz nową lokalną instancję
_M.push_back(xM); // kopiuje unique_ptr's
// fix:
_M.push_back(std::move(xM));

1 użytkowników online, w tym zalogowanych: 0, gości: 1