3

Sample code:

#include <string>
#include <set>

using namespace std;

class x
{
private:
  int i;
public:
  int get_i() const { return i; }
};

struct x_cmp
{
    bool operator()(x const & m1, x const & m2)
#if _MSC_VER
    const
#endif
    {
        return m1.get_i() > m2.get_i();
    }
};

std::set<x, x_cmp> members;

void add_member(x const & member)
{
    members.insert(member);
}

Invocations:

$ g++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ clang++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ icc -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ cl /c /std:c++14 /Za
<nothing>

Question: why msvc requires const while others don't? Or why others don't require const?

pmor
  • 5,392
  • 4
  • 17
  • 36
  • 1
    MSVC is correct. Your operator should be marked const because it is being used on a const object, and should be marked as such because it does not (_should not_) modify the object anyway. Turn up your warnings on the other compilers and they’ll complain too. – Dúthomhas Feb 03 '22 at 17:41
  • 2
    @Dúthomhas With warnings turned on they don't complain: https://godbolt.org/z/4dhMjYW56. Why? – pmor Feb 03 '22 at 17:57

1 Answers1

7

This is LWG2542. In C++14, the wording for the comparison operator said "possibly const", which was interpreted by GCC and Clang as meaning that the comparison operator was not required to be const qualified. MSVC always required it.

This is a wording defect, as comparison operators for associative containers should be const qualified. This was changed in C++17 to require the comparator to be const. This is a breaking change, so valid (though broken) C++14 code may fail to compile in C++17.

cigien
  • 57,834
  • 11
  • 73
  • 112