Problem with iterators

Hi, I wrote a simple program to test equality between 2 containers, but it's not working and I can't figure out why.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>

using namespace std;

template<class In, class C>
bool mequal(In beg, In end, C c)
{
	while ((beg != end) && (*beg == *c.begin()))
	{
		beg++;
		c.begin()++;
	}
		
	if (beg == end)
		return 1;
	else
		return 0;

}


int _tmain(int argc, _TCHAR* argv[])
{
	string a = "lol";
	string b = "lol";

	cout << mequal(a.begin(), a.end(), b) << endl;

	system("PAUSE");
	return 0;
}


It only works for strings of 1 letter.
c.begin()++;

What are you trying to do here? This line is effectively a no-op.

If you want to keep track of an iterator for your 'c' string, you'll need to make a new iterator. You can't change where the string begins.
I did not specified the & so it's a copy of the string, therefore I don't change the string?
c.begin() returns an iterator (a pointer to the front of the string).
You increment that pointer, but don't do anything with the result.
I do c.begin()++; and after (*beg == *c.begin()))
so I need to increment it.
Last edited on
You're not understanding what Disch and I are saying.
You're NOT changing the value of begin().

Your line 14 is equivalent to the following:
14
15
16
17
18
{  // nested scope
    string::iterator  iter;
    iter = c.begin();
    iter++;
}  // iter goes out of scope  

Last edited on
Ok so I modified my program to create new iterators from those in the parameters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>
#include <iterator>

using namespace std;

template<class In, class C>
bool mequal(In beg, In end, C c)
{
	typedef typename In::iterator iter;
	typedef typename C::iterator iterc;
	
	iter b = beg;
	iter e = end;
	iterc cb = c.begin();
	iterc ce = c.end();

	
	while (*b == *cb)
	{
		++b;
		++cb;
		if (b == e && cb == ce)
			return 1;
		else if (b == e || cb == ce)
			return 0;
	}
		
	return 0;

}


int _tmain(int argc, _TCHAR* argv[])
{
	string a = "lol";
	string b = "lol";
	

	cout << mequal(a.begin(), a.end(), b) << endl;

	system("PAUSE");
	return 0;
}


and I get plenty of errors when I build.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1
1>  ConsoleApplication7.cpp
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(15): error C2039: 'iterator' : is not a member of 'std::_String_iterator<std::_String_val<std::_Simple_types<char>>>'
1>          c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(45) : see reference to function template instantiation 'bool mequal<std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,std::string>(In,In,C)' being compiled
1>          with
1>          [
1>              In=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
1>  ,            C=std::string
1>          ]
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(18): error C2514: 'std::iterator' : class has no constructors
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(338) : see declaration of 'std::iterator'
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(19): error C2514: 'std::iterator' : class has no constructors
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(338) : see declaration of 'std::iterator'
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(24): error C2100: illegal indirection
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(24): error C2446: '==' : no conversion from 'int' to 'iter'
1>          The target type has no constructors
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(24): error C2088: '==' : illegal for struct
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(26): error C2675: unary '++' : 'iter' does not define this operator or a conversion to a type acceptable to the predefined operator
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(28): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'iter' (or there is no acceptable conversion)
1>          c:\program files (x86)\windows kits\8.1\include\shared\guiddef.h(192): could be 'bool operator ==(const GUID &,const GUID &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\system_error(410): or       'bool std::operator ==(const std::error_condition &,const std::error_code &) throw()'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\system_error(402): or       'bool std::operator ==(const std::error_code &,const std::error_condition &) throw()'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(507): or       'bool std::operator ==(const std::exception_ptr &,std::nullptr_t)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(502): or       'bool std::operator ==(std::nullptr_t,const std::exception_ptr &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(497): or       'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &)'
1>          while trying to match the argument list '(iter, iter)'
1>c:\users\ssmuel\desktop\programmation\c++\consoleapplication7\consoleapplication7\consoleapplication7.cpp(30): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'iter' (or there is no acceptable conversion)
1>          c:\program files (x86)\windows kits\8.1\include\shared\guiddef.h(192): could be 'bool operator ==(const GUID &,const GUID &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\system_error(410): or       'bool std::operator ==(const std::error_condition &,const std::error_code &) throw()'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\system_error(402): or       'bool std::operator ==(const std::error_code &,const std::error_condition &) throw()'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(507): or       'bool std::operator ==(const std::exception_ptr &,std::nullptr_t)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(502): or       'bool std::operator ==(std::nullptr_t,const std::exception_ptr &)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\exception(497): or       'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &)'
1>          while trying to match the argument list '(iter, iter)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
In is an iterator type which does not have a nested iterator type, so the compiler barfs on line 12 (which seems to correspond with line 15 in your actual code as opposed to that posted here.)
Last edited on
The 'beg' and 'end' are already iterators. Why did you touch them? Your problem was with 'c'.
I don't understand your advices. When I do c.begin()++; , it doesn't create a new iter because I tried to use it and it doesn't exists.
I don't understand your advices. When I do c.begin()++; , it doesn't create a new iter because I tried to use it and it doesn't exists.


c.begin() is a member function begin invoked on an object c which returns an object of type C::iterator. It does create a new iterator. c.begin()++ increments that new iterator, however that iterator ceases to exist at the end of the statement and so it is as if you had done nothing.
Ok so if ++ doesn't work to increment an iterator permanently, should I use +=1 instead?
No. You should change a non-temporary iterator. Your problem is not on how you change, but what you change.

On your second attempt you already have non-temporary iterators cb and ce. Use them.
Ok I finally got it working, I think sleeping helps clarifying all that ^^

Here is my new code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>

using namespace std;

template<class In, class C>
bool mequal(In beg, In end, C c)
{
	if (beg == end && c.size() == 0)
		return 1;
	else if (beg == end || c.size() == 0)
		return 0;
	
	typedef typename C::iterator cit;
	
	cit cb = c.begin();
	cit ce = c.end();
	
	while (*beg++ == *cb++)
	{
		if (beg == end && cb == ce)
			return 1;
		
		else if (beg == end || cb == ce)
			return 0;
	}
		
	return 0;

}


int _tmain(int argc, _TCHAR* argv[])
{
	string a = "allo mon ami";
	string b = "allo mon ami";

	cout << mequal(a.begin(), a.end(), b) << endl;

	system("PAUSE");
	return 0;
}


Thanks everybody!
Last edited on
Topic archived. No new replies allowed.