TL; DR: Can I expect the code below to be compiled to any C ++ 17 compatible C ++ toolchain (based on the current sentence in C ++ 17), and MSVC's refusal to do this is a mistake in their implementation?
#include <string_view> struct Foo : std::string_view {}; int main() { Foo f1{}; Foo f2{}; return f1 == f2; }
Explanation:
I have a class that is derived from std::string_view and does not implement its own comparison operators, because the semantics of std::string_view is exactly what I need, and I also want it to be comparable with, for example, a std::string .
However, if I try to compare two instances of this class, MSVC 2017 complains about multiple overloads with similar conversions:
example.cpp /opt/compiler-explorer/windows/19.10.25017/lib/native/include/xlocale(314): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc 8 : <source>(8): error C2666: 'std::operator ==': 3 overloads have similar conversions /opt/compiler-explorer/windows/19.10.25017/lib/native/include/exception(336): note: could be 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &) throw()' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/exception(341): note: or 'bool std::operator ==(std::nullptr_t,const std::exception_ptr &) throw()' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/exception(346): note: or 'bool std::operator ==(const std::exception_ptr &,std::nullptr_t) throw()' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/system_error(362): note: or 'bool std::operator ==(const std::error_code &,const std::error_code &) noexcept' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/system_error(370): note: or 'bool std::operator ==(const std::error_code &,const std::error_condition &) noexcept' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/system_error(378): note: or 'bool std::operator ==(const std::error_condition &,const std::error_code &) noexcept' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/system_error(386): note: or 'bool std::operator ==(const std::error_condition &,const std::error_condition &) noexcept' [found using argument-dependent lookup] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/xstring(970): note: or 'bool std::operator ==<char,std::char_traits<char>>(const std::basic_string_view<char,std::char_traits<char>>,const std::basic_string_view<char,std::char_traits<char>>) noexcept' /opt/compiler-explorer/windows/19.10.25017/lib/native/include/xstring(980): note: or 'bool std::operator ==<char,std::char_traits<char>,Foo&,void>(_Conv,const std::basic_string_view<char,std::char_traits<char>>) noexcept(<expr>)' with [ _Conv=Foo & ] /opt/compiler-explorer/windows/19.10.25017/lib/native/include/xstring(990): note: or 'bool std::operator ==<char,std::char_traits<char>,Foo&,void>(const std::basic_string_view<char,std::char_traits<char>>,_Conv) noexcept(<expr>)' with [ _Conv=Foo & ] 8 : <source>(8): note: while trying to match the argument list '(Foo, Foo)' Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x64 Copyright (C) Microsoft Corporation. All rights reserved. Compiler exited with result code 2
I do not know why the first few overloads (for example, with std::error_code ) are listed at all. Since the error message itself only speaks of three overloads, I think they are only available for completeness, but are not part of the problem.
What bothers me is two overloads:
bool std::operator ==<char,std::char_traits<char>,Foo&,void>(_Conv,const std::basic_string_view<char,std::char_traits<char>>) noexcept(<expr>) bool std::operator ==<char,std::char_traits<char>,Foo&,void>(const std::basic_string_view<char,std::char_traits<char>>,_Conv) noexcept(<expr>)
I could not find mention of them on cppreference.com , and the code compiles for clang and gcc: https://godbolt.org/g/4Lj5qv , so they probably are not present in their implementation.
So my question is
- Is their existence actually permitted (or even authorized) by the expected C ++ 17 standard, or is it an error in MSVC?
- If something like this is allowed in the standard, appropriate C ++ standard library, is there a regular workaround that does not require me to implement all the comparators (I know that they are trivial to write, but this should not be necessary, and I would have to repeat the process for several types).
EDIT :
In fact, Foo is an immutable string class, very similar to this: https://codereview.stackexchange.com/questions/116010/yet-another-immutable-string , but in order to simplify the design, I wanted to replace my manual str_ref with std::string_view