[llvm-bugs] [Bug 48611] user-defined template operator < not used
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Dec 31 01:29:43 PST 2020
https://bugs.llvm.org/show_bug.cgi?id=48611
Tobias Loew <tobi at die-loews.de> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|INVALID |---
Status|RESOLVED |REOPENED
--- Comment #5 from Tobias Loew <tobi at die-loews.de> ---
Hi David,
this bug is not about overload-resolution between functions and
template-functions. Below is a shorter example with only one enum:
First, a quote from the standard [over.built] 1.:
/*********************************************
The candidate operator functions that represent the built-in operators defined
in [expr.compound] are specified in this subclause. These candidate functions
participate in the operator overload resolution process as described in
[over.match.oper] and are used for no other purpose.
[Note 1: Because built-in operators take only operands with non-class type, and
operator overload resolution occurs only when an operand expression originally
has class or enumeration type, operator overload resolution can resolve to a
built-in operator only when an operand has a class type that has a user-defined
conversion to a non-class type appropriate for the operator, or when an operand
has an enumeration type that can be converted to a type appropriate for the
operator. Also note that some of the candidate operator functions given in this
subclause are more permissive than the built-in operators themselves. As
described in [over.match.oper], after a built-in operator is selected by
overload resolution the expression is subject to the requirements for the
built-in operator given in [expr.compound], and therefore to any additional
semantic constraints given there. If there is a user-written candidate with the
same name and parameter types as a built-in candidate operator function, the
built-in operator function is hidden and is not included in the set of
candidate functions. — end note]
*****************************************/
The last sentence of Note 1 states, that built-in operators are hidden when a
candidate with the same name and parameter types exists
/******************************************************
#include <iostream>
enum E2 {
e2_a
};
template<class E>
inline bool operator<(E, E) { // (1)
return true;
}
int main()
{
if (E2::e2_a < E2::e2_a) { // (2)
std::cout << "user-defined operator used for E2\n";
} else {
std::cout << "builtin operator used for E2\n";
}
}
************************************************************/
For the operator < in line (2) there are two candidates:
- the user-defined template in line (1)
- the builtin operator < for enum E2
As both have the signature "bool <(E2,E2)", the built-in operator should be
hidden, and therefor the user-defined should be selected.
Here comes even more evidence, why the behaviour of the compiler seems odd:
1.
When in the example above the user-defined template-operator is replaced by
inline bool operator<(E2, E2) {
return true;
}
then the user-defined operator is selected.
2. When a different operator like ^, &, &&, | or || is used, then the
user-defined operator is also used (I know that the return type is odd):
/***************************************************
#include <iostream>
enum E2 {
e2_a
};
template<class E>
inline bool operator&(E, E) {
return true;
}
int main()
{
if (E2::e2_a & E2::e2_a) {
std::cout << "user-defined operator used for E2\n";
} else {
std::cout << "builtin operator used for E2\n";
}
}
***************************************************/
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201231/786f50a0/attachment.html>
More information about the llvm-bugs
mailing list