UPDATED SOLUTION:
With my particular problem, the sort call was inside a Render function marked as const. By either removing the const (not my preference) or putting the sort in another function (in this case, the bottom of my Update), the problem is taken care of. As several answerer’s suggested, it WAS a const problem, just not where I was looking!
ORIGINAL PROBLEM
I have an std::vector list of pointers to objects declared thus:
std::vector<Object*> myObjects;
I’m trying to sort them by a member data through a getter… I have a sort predicate as well. Here’s the sort predicate followed by the std::sort call:
bool SortByDistance(const Object* o1, const Object* o2)
{
return o1->GetDist() < o2->GetDist();
}
Sort call:
std::sort(myObjects.begin(), myObjects.end(), SortByDistance);
I’m getting a dozen or so errors though complaining about assignment of read-only location or similar:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/c++/4.2.1/bits/stl_algo.h:2385: error: assignment of read-only location
I’m sure it is something silly I’m doing… could someone help shed some light? I’m rusty with my C++ and just getting back into it! Any suggestions would be much appreciated.
UPDATE
I’m still getting the same error, despite trying iammilind’s suggestions to remove the const altogether or ensure that const is 100% (in other words, I’ve tried adding const to the end of the SortByDistance predicate, as well as removing it from the situation altogether.
I’m thinking one of the commenters may be onto something by suggestion I am doing something stupid and dangerous: storing raw pointers to objects in STL containers. I’ve never done this any differently though… what are the reasons for storing objects in containers that aren’t dynamically allocated on the heap? I assume if I’m not dealing with raw pointers, a lot of the complexity of my sort problem goes away.
I’m currently creating my Objects like this:
std::vector<Object*> myObjects;
Object* tempObject = new Object;
myObjects.push_back(tempObject);
I of course release that memory when the program finishes, but it sounds like this is just a bad idea in general?
On a more related note (to the question I asked), here’s the code in stl_algo.h that is complaining:
template<typename _RandomAccessIterator, typename _Compare>
void
__insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
if (__first == __last) return;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
{
typename iterator_traits<_RandomAccessIterator>::value_type
__val = *__i;
if (__comp(__val, *__first))
{
std::copy_backward(__first, __i, __i + 1);
*__first = __val; // this line is the one complaining about read-only assignment
}
else
std::__unguarded_linear_insert(__i, __val, __comp);
}
}
Despite trying various const/no-const solutions, I still get the same error. If I comment out the line that is running the sort:
std::sort(myObjects.begin(), myObjects.end(), SortByDistance);
the errors, of course, go away.
Just from your code, I guess that your
Object::GetDist()method is notconst. In C++, aconstobject of aclasscan call onlyconstmembers.If this is the case then you have 2 ways to remove this error.
(1) Make
GetDistasconst:(2) Change
SortByDistance: