Thread: Const_ holding me back

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    11

    Const_ holding me back

    Hi, I'm new around these parts. I've been doing something for uni and I've been making very steady progress on an assignment until I ran into this little problem. Might be trivial, but staring at it for the last hour doesn't make it any easier.

    I'm trying to use set_intersection, but this const error is there. I don't know where else to look to rectify this problem? Can someone shed some light on this please?

    Thanks in advance,
    Somedude.

    Code:
    /usr/include/c++/4.0.0/bits/stl_algo.h: In function ‘_OutputIterator std::set_intersection(_InputIterator1, _InputIterator1,
    _InputIterator2, _InputIterator2, _OutputIterator) [with _InputIterator1 = std::_Rb_tree_const_iterator<Hit>, _InputIterator2 = 
    std::_Rb_tree_const_iterator<Hit>, _OutputIterator = std::_Rb_tree_const_iterator<Hit>]’:
    /trunk/subNode.cc:171:   instantiated from here
    /usr/include/c++/4.0.0/bits/stl_algo.h:4233: error: passing ‘const Hit’ as ‘this’ argument of ‘Hit& Hit::operator=(const Hit&)’ discards qualifiers
    Code:
    Hits evaluate(Hits left_list, Hits right_list, Operation op) {
    	Hits result;
    	//vector<Hit>::iterator it_left, it_right;
    	
    	switch (op) {
    		case '0' : 			// 'AND' operator
    			set_intersection( left_list.results.begin(), left_list.results.end(),
    					  right_list.results.begin(), right_list.results.end(),
    					  result.results.begin() );   <-- error occurs here
    			return result;
    		break;
    ...
    Code:
    class Hits {
    public:
    	Hits() {}
    	std::set<Hit> results;
    	void add(Hit h) { results.insert(h); }
    };

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is that a std::set iterator treats the element that it points to as const, so you cannot just dereference and assign. This makes sense because arbitrarily changing what the iterator points to can mess up the order guaranteed by the std::set.

    Offhand, I am not sure what is the correct approach here. Maybe you should use the std::inserter adapter, e.g.,
    Code:
    set_intersection( left_list.results.begin(), left_list.results.end(),
        right_list.results.begin(), right_list.results.end(),
        inserter(result.results, result.results.begin()));
    EDIT:
    Ah, std::inserter works, but my example demonstrated it incorrectly, and is now fixed. Note that you should #include <functional> for std::inserter.
    Last edited by laserlight; 05-19-2009 at 10:52 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    11
    There is so much left to learn...sigh. But I can tick this thing off that list.

    So I used this code, and compiled. All good (EDIT: yeah, I looked up cplusplus reference for the definition, but I included iterator instead, still works)
    Code:
    inserter(result.results, result.results.begin())
    Thank you very much for the prompt help!



    /cookie
    Last edited by somedude; 05-19-2009 at 10:59 AM.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You can probably achieve the same effect with:

    Code:
    result.results = left_list.results;
    result.results.insert(right_list.results.begin(), right_list.results.end());
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by laserlight View Post
    Ah, std::inserter works, but my example demonstrated it incorrectly, and is now fixed. Note that you should #include <functional> for std::inserter.
    I thought std::inserter was in <iterator> ? I suppose <functional> probably includes <iterator>
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    11
    Quote Originally Posted by anon View Post
    You can probably achieve the same effect with:

    Code:
    result.results = left_list.results;
    result.results.insert(right_list.results.begin(), right_list.results.end());
    That would be the same as set_union, which belongs to the other case.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Thank you very much for the prompt help!
    You're welcome

    Quote Originally Posted by anon
    You can probably achieve the same effect with:
    No, that would be a set union, not an intersection. I was looking through the std::set interface for something that could be directly used for a set union, but did not find anything, so std::set_intersection seemed like the best option in the end.

    Quote Originally Posted by brewbuck
    I thought std::inserter was in <iterator> ? I suppose <functional> probably includes <iterator>
    Double checked, and you are right. Looks like I have been making incorrect includes for std::back_inserter too, but probably never noticed it because I typically also include <iterator> in such cases
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  2. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  3. Replies: 6
    Last Post: 12-06-2005, 09:23 AM
  4. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM