-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Description
over.match.oper states: "If a rewritten operator== candidate is selected by overload resolution for an operator @, its return type shall be cv bool."
Presumably based on that language, Clang rejects the following code:
struct foo {};
template <typename T>
auto operator==(foo, T) { return true; }
void bar() {
0 == foo{};
}With this error:
<source>:7:7: error: return type 'auto' of selected 'operator==' function for rewritten '==' comparison is not 'bool'
7 | 0 == foo{};
| ~ ^ ~~~~~
<source>:4:6: note: declared here
4 | auto operator==(foo, T) { return true; }
| ^
However, GCC, MSVC and EDG all accept it, as shown in Compiler Explorer here: https://godbolt.org/z/46aaPvn46
I think Clang is being overly restrictive here. The fact that the operator== returns auto doesn't violate that "its return type shall be cv bool," since auto is a placeholder for a return type, not a return type itself. The standard seems to make this distinction in dcl.spec.auto:
A placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid. If the function declarator includes a trailing-return-type ([dcl.fct]), that trailing-return-type specifies the declared return type of the function. Otherwise, the function declarator shall declare a function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded return statements, if any, in the body of the function ([stmt.if]).
Notice the distinction between "declared return type" (which is auto or decltype(auto)) and "return type" (which is "deduced from non-discarded return statements [...] in the body of the function").
Metadata
Metadata
Assignees
Labels
Type
Projects
Status