5

I have a class with std::set<const std::string> members which compiles fine in Clang 10.0.1 on macOS, but does not with GCC 5.4.0. MRE below

#include <set>
#include <string>

class Foo {
  std::set<const std::string> bar; ///<--- error ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const std::__cxx11::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::__cxx11::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::__cxx11::basic_string<char>&]’ cannot be overloaded

public:
  Foo() {}
};

int main(int argc, char *argv[]) {
  Foo f;
  return 0;
}

Compiler invocation:

/usr/bin/g++ -std=c++11 test.cpp

If instead I use non-const string it works. Is this a problem of an outdated standard library version?

oarfish
  • 4,116
  • 4
  • 37
  • 66
  • @ChrisMM, cppreference lists the `CopyAssignable` requirement for `T` in the case of `std::vector`, but there is no such a requirement for `std::set`. – Evg Apr 23 '20 at 12:22
  • 1
    @Evg, it's the allocator that has the requirement … Which set uses – ChrisMM Apr 23 '20 at 12:24
  • Interesting, so the fact that Clang compiles this is implementation-defined behaviour or simply a standards violation? – oarfish Apr 23 '20 at 12:33
  • It is not a violation because requirements on `T` are broadened, not narrowed. – Evg Apr 23 '20 at 12:40
  • I can't seem to find specification of this behaviour in cppreference.com. Can it only be deduced from the actual standard text or am I missing something? – oarfish Apr 23 '20 at 13:21
  • I used the standard draft. In n4713, it's Table 30 for the requirements of allocator (`[allocator.requirements]`) – ChrisMM Apr 23 '20 at 13:31
  • 1
    [Here it is](http://eel.is/c++draft/allocator.requirements#tab:allocator.req.var). – Evg Apr 23 '20 at 13:46

0 Answers0