On Tue, 24 Jan 2017 17:54:25 +0100
Ralf Goertz <m...@myprovider.invalid> wrote:
> Am Tue, 24 Jan 2017 16:24:34 +0000
> schrieb Chris Vine <chris@cvine--nospam--.
freeserve.co.uk>:
[snip]
> > I didn't even know that was a requirement, but it seems a sensible
> > one so as to maintain referential transparency: that is, so that
> > ordering is correctly maintained. If the operator could mutate the
> > state of the object of type cmp_int of which it is a member,
> > different invocations of the operator with the same arguments could
> > yield different results. Your cmp_int type does not have
> > non-static data members; but it might have.
>
> But that's exactly my point. If cmp_int were something like this:
>
> struct cmp_int {
> static bool counter;
> bool operator()(const int &x,const int &y) const
> {
> counter=!counter;
> return (counter ? x < y : x > y);
> }
> };
>
> it would compile for const and non const variables of type
> std::set<int,cmp_int>. So I don't see how the const declaration of the
> operator helps. So why is it necessary?
So far as the ability of a const member function to mutate static
member data is concerned, or its ability to mutate global or static
data at namespace scope as well for that matter, I guess you just have
to accept that as a matter of language specification in C++ 'const' does
not mean 'pure'.
But on your larger point about std::set, on reflection I think you are
right. The requirement to maintain referential transparency for the
comparison operator type should apply irrespective of whether the
std::set object is const or not. There may be an argument that for a
non-const set, the comparison operator should be able to arbitrarily
mess around with ordering, but that doesn't seem a very good argument.
This may be just a miscellaneous wart in C++.
Chris