[cfe-dev] Is this a bug?

Hubert Tong via cfe-dev cfe-dev at lists.llvm.org
Sun Dec 10 07:05:51 PST 2017

Converting your case:
template <typename T, typename Policy>
struct Handle
  template <typename Rhs> bool operator <(Rhs rhs) const;

struct Special;

template <typename LHS_T2, typename RHS_T2>
bool operator <(Handle<Special, LHS_T2> lhs, Handle<Special, RHS_T2> rhs);

bool f() {
  Handle<Special, int> h1, h2;
  return h1 < h2;


template <typename T, typename Policy> struct Handle { };
struct Special;

template <typename Rhs>
bool operator <(*const Handle<Special, int> &*, Rhs);

template <typename LHS_T2, typename RHS_T2>
bool operator <(Handle<Special, LHS_T2>, Handle<Special, RHS_T2>);

bool f() {
  Handle<Special, int> h1, h2;
  return h1 < h2;

Gives the same behaviour between Clang and GCC.

On Sun, Dec 10, 2017 at 3:11 AM, Evan Driscoll via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> In our code base, we have the following (code linked below):
> * A class template for "handles" to objects of assorted types,
>   Handle<T, Policy>; T is the actual element type
> * Handle contains a member operator < (and others). It uses the
>   "address" of the object to do the comparison.
> * There is a special class where we want to customize operator <
>   so it looks into the associated object, so we have a templated
>   overload free function of operator< on Handle<Special, T2>.
> I've got my doubts as to the sanity of this design in some ways, but I
> don't think I can reasonably change it.
> This compiles with GCC [1], and with MSVC [2], but Clang gives an error
> about the two operator<s being ambiguous, starting with 3.5 [3].
> Perhaps importantly, the operator< member of Handle has this "signature":
>    template <typename T, typename Policy>
>    template <typename RHS_Handle>
>    bool Handle<T, Policy>::operator< (RHS_Handle const &)
> and the free function has this signature:
>     template <
>         typename LHS_T, typename LHS_Policy,
>         typename RHS_T, typename RHS_Policy>
>     bool operator<  (
>         Handle<LHS_T, LHS_Policy> lhs,
>         Handle<RHS_T, RHS_Policy> rhs);
> At least if we ignore the references and cv-quals, my understanding is
> that the latter function should have priority over the former because it's
> more specialized -- the second parameter is Handle<RHS_T, RHS_Policy>
> rather than a generic RHS_Handle type.
> So if the function is called with
>     Handle<MyType, SomePolicy> h1, h2;
>     h1 < h2;
> then it should not be ambiguous, and select the free overload. However,
> perhaps the cv-qualification matters, and GCC/MSVC get it wrong?
> Credit to OmegaNaughtEquals1 on Reddit who pointed me to some standards
> text that seems to support the position that it should work (maybe... it's
> too late to really tell what should be happening with the cv/ref stuff) [4].
> If I change the free function to take 'lhs' by reference, then Clang
> compiles it [5].
> I'm happy to report this to the bug tracker if that's what I should do --
> I just wasn't sure if I should with something that I'm not sure is a bug.
> Thanks,
> Evan
> [1] GCC compiles it: https://godbolt.org/g/9EaoYh
> [2] MSVC does too: https://godbolt.org/g/ubXeC3
> [3] Clang's error: https://godbolt.org/g/MhNEky
> [4] Reddit thread: https://www.reddit.com/r/cpp_questions/comments/
> 7ir4j5/-/
> [5] Modified copy with ref parameter: https://godbolt.org/g/v9HtuH
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171210/0dd66b1a/attachment-0001.html>

More information about the cfe-dev mailing list