Template sort being cast to const

closed account (o1vk4iN6)
I have this bit of code, which was working, I changed something in another part of code and recompiled and now all of a sudden I'm getting "you cannot assign variable that is const".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Obj { // fixed from class
     int level;
     const char* name;
};

bool funct_sort_obj(Obj* lhs, Obj* rhs)
{
     if(lhs->level != rhs->level) 
          return lhs->level < rhs->level;

     return strcmp(lhs->name, rhs->name) < 0;
}

int main()
{
     std::vector<Obj*> objs; 

     // fill with "new" operator

     sort(objs.begin(), objs.end(), funct_sort_obj);
}


I look at the trace and I notice that one of the types is being reset to "Obj * const *". I'm using MSVC compiler.


std::_Sort(_RanIt,_RanIt,_Diff,_Pr)
being compiled with
[
_RanIt=Obj *const *,
_Diff=__w64 int,
_Pr=int (__cdecl *)(Obj *, Obj *)
]


Edit:

It would seem, begin() and end() are being cast to const_iterator for some reason?

Last edited on
This is because in class Obj your members are all private by default (in contrast to structs) and thus you cannot access them in funct_sort_obj.

Insert public and it will work. Even better, you can provide const getter functions and change the signature to int funct_sort_obj(const Obj* lhs, const Obj* rhs).
closed account (o1vk4iN6)
That's a mistake on my end in my example, I am using struct, sorry.
So its still not compiling? On my Linux box the fixed code with struct compiles fine.
You can either try to force getting non const iterators ...

1
2
3
std::vector<Obj*>::iterator beg = objs.begin();
std::vector<Obj*>::iterator end = objs.end();
sort(beg, end, funct_sort_obj);

... or make const getter methods as mentioned before.
closed account (o1vk4iN6)
The problem isn't the getter functions, it's when it tries to change the value (since this is a sort method) so the error is when the sort() function tries assigning a value to the iterator:

*_First = *_Next;

I have a backup of my source code where it works fine, for some reason it decided to start using the const overloaded function of begin(). There isn't anything forcing it to be const and there isn't anything forcing it not to be, I guess there is some sort of error for Microsoft's compiler as the error only started happening when I created a for loop using iterators.

edit:

error C2440: 'initializing' : cannot convert from 'std::_Vector_const_iterator<_Ty,_Alloc>' to 'std::_Vector_iterator<_Ty,_Alloc>'


Get that error using above code, I'll try a different compiler...
Last edited on
This sounds really like a const-correctness problem. Is it possible that your objs variable is somewhere passed as const into some subroutine? In this case you would always get const iterators from that vector. You can provide more code if you want.
Topic archived. No new replies allowed.