CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    May 2007
    Location
    Bangalore India
    Posts
    262

    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.

  2. #2
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    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.

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  4. #4
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    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.
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  5. #5
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    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.

  6. #6
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    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.
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  7. #7
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Accessing and changing elements in a std::set

    Quote Originally Posted by Ajay Vijay View Post
    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.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  9. #9
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Accessing and changing elements in a std::set

    Quote Originally Posted by Lindley View Post
    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.

  10. #10
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Accessing and changing elements in a std::set

    Quote Originally Posted by Lindley View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured