[libcxx-commits] [PATCH] D108250: [libc++][spaceship] Implement std::tuple::operator<=>

Kent Ross via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 24 15:44:06 PDT 2021


mumbleskates marked 2 inline comments as done.
mumbleskates added inline comments.


================
Comment at: libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/three_way.pass.cpp:172-173
+    typedef std::tuple<int, unsigned long, SpaceshipNoEquals> T2;
+    // Spaceship operator with no == operator falls back on the < operator and weak ordering.
+    ASSERT_SAME_TYPE(decltype(T1() <=> T2()), std::weak_ordering);
+  }
----------------
mumbleskates wrote:
> mumbleskates wrote:
> > Quuxplusone wrote:
> > > This is somewhat counterintuitive, right? What is the behavior of `T1() == T2()` in this case — does it call tuple's `operator==`, or does it not exist? Should we test that?
> > `operator==` does not fallback to be rewritten in terms of `operator<=>`, so yeah tuple's `operator==` is expectedly undefined in this case.
> > 
> > It doesn't really hurt to test it, but I think this would belong in the `eq.pass` test instead.
> I just spent like 45 minutes trying to make this test work. it can be impossible to use `==` without error, as expected, but when a no-`==` type is part of a tuple i cannot get that to be detectable with sfinae or even with concepts and it's unclear to me why that is.
> 
> the operator is implemented as a call to a cascade of template functions in template classes, but the end result is still ill formed and (i would think) should be eliminated, and it's beyond my current ability to see why.
Okay. `operator==` is not SFINAE-friendly, and does not eliminate itself from participation when the subsidiary types don't have the operator. `std::pair` doesn't do this either. It's probably possible for us to implement this but that seems entirely beyond the scope here, isn't especially standard, and would probably be a lot of work besides. Suffice to say that calling calling the `operator==` when any of the subsidiary types are missing that operator expectedly causes an error.

The main reason we can easily SFINAE-test `operator<=>` is because its //return type// is dependent on everything it's going to do, so all the steps it's going to take when it executes are in a way traced out ahead of time in the function's signature.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108250/new/

https://reviews.llvm.org/D108250



More information about the libcxx-commits mailing list