<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><span class="vcard"><a class="email" href="mailto:tobi@die-loews.de" title="Tobias Loew <tobi@die-loews.de>"> <span class="fn">Tobias Loew</span></a>
</span> changed
<a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - user-defined template operator < not used"
href="https://bugs.llvm.org/show_bug.cgi?id=48611">bug 48611</a>
<br>
<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>What</th>
<th>Removed</th>
<th>Added</th>
</tr>
<tr>
<td style="text-align:right;">Resolution</td>
<td>INVALID
</td>
<td>---
</td>
</tr>
<tr>
<td style="text-align:right;">Status</td>
<td>RESOLVED
</td>
<td>REOPENED
</td>
</tr></table>
<p>
<div>
<b><a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - user-defined template operator < not used"
href="https://bugs.llvm.org/show_bug.cgi?id=48611#c5">Comment # 5</a>
on <a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - user-defined template operator < not used"
href="https://bugs.llvm.org/show_bug.cgi?id=48611">bug 48611</a>
from <span class="vcard"><a class="email" href="mailto:tobi@die-loews.de" title="Tobias Loew <tobi@die-loews.de>"> <span class="fn">Tobias Loew</span></a>
</span></b>
<pre>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";
}
}
***************************************************/</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>