-
May 6th, 2010, 06:55 AM
#1
Accessing and changing elements in a std::set
Code:
class TestClass
{
public:
TestClass(string name, string profession): _name(name), _profession(profession)
{
}
bool operator <(const TestClass& testClass) const
{
if(_name.compare(testClass._name) <= 0)
return false;
return true;
}
string _name;
string _profession;
};
int main(int argc, char** argv)
{
set<TestClass> test;
TestClass t1("Prashant", "Eng");
TestClass t2("Prashant1", "Eng1");
TestClass t3("Prashant2", "Eng2");
TestClass t4("Prashant3", "Eng3");
test.insert(t1);
test.insert(t2);
test.insert(t3);
test.insert(t4);
for(set<TestClass>::iterator it = test.begin(); it != test.end(); it++)
{
(*it)._name = "asdasdasd"; //Here it gives compilation error.
}
}
In function `int main(int, char**)':
helloworld.cpp:50: error: passing `const std::string' as `this' argument of `std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>:perator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' discards qualifiers
I need to figure out a way to modify an element in the set, through iterator..
Thanks in Advance for your help.
Dont forget to rate my post if you find it useful.
-
May 6th, 2010, 07:01 AM
#2
Re: Accessing and changing elements in a std::set
According to strict standard, set iterators can't be used to modify what they are pointing to (they are basically just const_iterators).
This is because the value of objects in a set are also a "key", and since that key is part of the set internals, modifying it could be very dangerous. In your case, even if it compiled, it would have broken your set.
There is a bit of disagreement over this. Some say there are legitimate cases where you should be able to modify the values, others say it is just plain too dangerous.
The correct way to do it is to copy the value elsewhere, remove the value from the set, modify the copied value, re-insert the modified value. Using hints correctly, it's mostly code overhead, but performance is good.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 6th, 2010, 09:21 AM
#3
Re: Accessing and changing elements in a std::set
If you're going to modify things, consider whether you really want a set or not. It may turn out that another container like a std:riority_queue is better. Depends on your specific problem.
-
May 6th, 2010, 10:44 AM
#4
Re: Accessing and changing elements in a std::set
The value of an element in a set may not be changed directly. Instead, you must delete old value and insert elements with new value.
-
May 6th, 2010, 10:54 AM
#5
Re: Accessing and changing elements in a std::set
Why does a set have an iterator type? I mean, as opposed to only a const_iterator?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 6th, 2010, 11:08 AM
#6
Re: Accessing and changing elements in a std::set
Good question! Here are my two cents:
- To maintain consistency among other container classes, so that your code doesn't break of you change the base container (like from set to vector).
- Constant object will call const begin (and other functions), which would return const_interator. Otherwise, it would (should) return non-const iterator.
- Functions that require non-constant iterator would work.
Disclaimer: My suggestions are only indicative, based on my knowledge.
-
May 6th, 2010, 11:33 AM
#7
Re: Accessing and changing elements in a std::set
Originally Posted by Ajay Vijay
Good question! Here are my two cents:
- To maintain consistency among other container classes, so that your code doesn't break of you change the base container (like from set to vector).
- Constant object will call const begin (and other functions), which would return const_interator. Otherwise, it would (should) return non-const iterator.
- Functions that require non-constant iterator would work.
Disclaimer: My suggestions are only indicative, based on my knowledge.
Well if you change container, and you were using normal iterators it should mean that you are using them to modify values, so the code will break anyways.
That said, most people don't go through the hassle of of using const_iterator unless they must. So that is probably it.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 6th, 2010, 11:41 AM
#8
Re: Accessing and changing elements in a std::set
Eh, personally I use const_iterator whenever possible....
And yes, I read the Effective STL Item which says to prefer iterator to const_iterator and reverse_iterator, but I wasn't convinced. I don't think the choice between const_iterator and iterator is any different than normal const-correctness.
-
May 6th, 2010, 11:58 AM
#9
Re: Accessing and changing elements in a std::set
Originally Posted by Lindley
Eh, personally I use const_iterator whenever possible....
And yes, I read the Effective STL Item which says to prefer iterator to const_iterator and reverse_iterator, but I wasn't convinced. I don't think the choice between const_iterator and iterator is any different than normal const-correctness.
Actually, I believe he recommends not mixing them. For example, if you call transform between first and last, don't make first an iterator, and last a const_iterator. Even if you don't plan on modifying last (and you shouldn't), most stl's template implementation just weren't written to deal with first and last of different types. Not to mention type resolution.
That said, given that a "const iterator" and "const_iterator" aren't the same thing (at all), I know it confuse some coders. I know I've had somebody ask me why my const_iterators were also const defined. Nothing dramatic, but there is a bit of confusion.
Anyways, I think the bottom line is that const-correctness is not MANDATORY, and not giving a normal iterator to set would break code that is otherwise fine. Just not 100% const compliant.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 7th, 2010, 03:51 AM
#10
Re: Accessing and changing elements in a std::set
Originally Posted by Lindley
Eh, personally I use const_iterator whenever possible....
Me too.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|