Search code examples
c++visual-c++c++14const-correctnessstdset

MSVC: C++14: std:set: comparison function: why "const" is required?


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?


Solution

  • 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.