[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;
}
to
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.html>
More information about the cfe-dev
mailing list