Problem with iterators

Aug 8, 2014 at 3:05pm
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.
Aug 8, 2014 at 3:07pm
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.
Aug 8, 2014 at 3:22pm
I did not specified the & so it's a copy of the string, therefore I don't change the string?
Aug 8, 2014 at 4:05pm
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.
Aug 8, 2014 at 4:35pm
I do c.begin()++; and after (*beg == *c.begin()))
so I need to increment it.
Last edited on Aug 8, 2014 at 4:36pm
Aug 8, 2014 at 5:33pm
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 Aug 9, 2014 at 1:42pm
Aug 8, 2014 at 9:30pm
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 ==========
Aug 8, 2014 at 9:55pm
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 Aug 8, 2014 at 9:55pm
Aug 8, 2014 at 9:58pm
The 'beg' and 'end' are already iterators. Why did you touch them? Your problem was with 'c'.
Aug 8, 2014 at 11:04pm
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.
Aug 8, 2014 at 11:21pm
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.
Aug 9, 2014 at 2:39pm
Ok so if ++ doesn't work to increment an iterator permanently, should I use +=1 instead?
Aug 9, 2014 at 3:07pm
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.
Aug 10, 2014 at 12:27pm
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 Aug 10, 2014 at 2:25pm
Topic archived. No new replies allowed.