[libcxx-commits] [PATCH] D92725: [libc++] [LWG2993] reference_wrapper<T> conversion from U&&

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Dec 10 17:53:29 PST 2020

Quuxplusone added inline comments.

Comment at: libcxx/include/__functional_base:396
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(_VSTD::declval<_Up>()))) {
+        type& __f = static_cast<_Up&&>(__u);
+        __f_ = _VSTD::addressof(__f);
curdeius wrote:
> Is there a difference between your approach, i.e. putting this in the ctor's body, and putting it into the initializer list?
This is how it's formally specified in LWG2993 — "Creates a variable `r` as if by `T& r = std::forward<U>(u)`, then constructs a `reference_wrapper` object that stores a reference to `r`."
I'm not aware of any //specific// difference between what I wrote here and a D40259-style

    : __f_(_VSTD::addressof(__bind(static_cast<_Up&&>(__u))))
{ }

but then I haven't thought hard about it. Basically I don't see any //advantage// to diverging from the exact "as-if-by" wording. Going our own way here can potentially make us wrong, but it can't make us any more right. :)

> Just to understand, how is your approach simpler than the one in D40259?

One fewer template parameter; exploit some recently added libc++ helpers like `__is_same_uncvref`; `static_cast<_Up&&>` versus `std::forward<_Up>`... I guess that's all. The implementation technique is basically the same. The lengthy comment threads on D40259 made me think the implementation was longer than it really was. :)  There's some obsolete stuff in those comments too, like references to `__void_t` when the patch no longer uses `__void_t`.

  rG LLVM Github Monorepo



More information about the libcxx-commits mailing list