 |
 |
 |
 |
 |
Author |
Message |
Tyche
Joined: 13 May 2005 Posts: 176 Location: Ohio, USA
|
Posted: Wed Apr 19, 2006 3:24 pm Post subject: STL assign |
|
|
Code: |
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
string s1;
string s2("stl sucks");
string::const_iterator p = s2.begin();
p++;
s1.assign(p, s2.end() - 1);
cout << s1 << endl;
return 0;
}
|
Why in the hell doesn't this compile?
No that's not really the question.
It's more like why doesn't assign() accept const_iterator? |
|
Back to top |
|
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
Author |
Message |
Gromble
Joined: 08 Oct 2005 Posts: 23
|
Posted: Wed Apr 19, 2006 5:44 pm Post subject: Re: STL assign |
|
|
According to the documentation I have, string::assign() takes string::size_type arguments, not string::iterator or string::const_iterator arguments. So your assign() options for s2 to s1 are...
s1.assign(s2); // copy entire string
s1.assign(s2, <length>); // copy first <length> chars
s1.assign(s2, <index>, <length>); // copy <length> chars starting at <index> |
|
Back to top |
|
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
Author |
Message |
Tyche
Joined: 13 May 2005 Posts: 176 Location: Ohio, USA
|
Posted: Wed Apr 19, 2006 6:49 pm Post subject: |
|
|
This works:
Code: |
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
string s1;
string s2("stl sucks");
string::iterator p = s2.begin();
const string s3("anally const correct");
string::const_iterator p2 = s3.begin();
p++; p2++;
s1.assign(p, s2.end() - 1);
cout << s1 << endl;
s1.assign(p2, s3.end() - 1);
cout << s1 << endl;
return 0;
}
|
I figured it out. begin() and end() return const_iterators only if the string is const.
So while this is okay:
assign (const InputIterator, const InputIterator)
assign (InputIterator, InputIterator)
Neither of these is legal:
assign (const InputIterator, InputIterator)
assign (InputIterator, const InputIterator) |
|
Back to top |
|
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
Author |
Message |
Kaz

Joined: 05 Jun 2005 Posts: 24 Location: Hampshire, UK
|
Posted: Thu Apr 20, 2006 3:17 pm Post subject: |
|
|
Ah, here's why. According to my copy of TC++PL, the function for string assignment with iterators is:
Code: |
template <class In>
basic_string& assign(In first, In last)
|
What happened is that one of your arguments was an iterator, the other a const_iterator. Thus, there was no match to this function, because the two types passed in must be the same. However, iterator is convertible to const_iterator, so you can have:
Code: |
string x("foobar!");
string::iterator begin = x.begin();
string::const_iterator end = x.end();
string y;
y.assign(string::const_iterator(begin), end);
|
Edit/Addendum: In retrospect, they could have used different template types for each argument. The reason they didn't, of course, was to make it difficult for the user to try and assign a range from two disparate objects. However, the technology now exists to check at compile-time whether one type is convertible to another, so this could be improved. |
|
Back to top |
|
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
 |
 |
 |
 |
|
 |