[PATCH] [libcxx] SFINAE-friendly common_type

Agustín Bergé kaballo86 at hotmail.com
Fri May 1 11:17:25 PDT 2015


In http://reviews.llvm.org/D6964#164655, @EricWF wrote:

> Just so I'm sure I understand: This implementation applies `decay<T>`  for ever pair of types in `common_type<T...>` even though N2408 says `decay` is only applied to the final type?


That sounds correct. In other words, it applies as much `decay` and in the same places as C++11 `common_type` used to do.

In http://reviews.llvm.org/D6964#164665, @EricWF wrote:

> @K-ballo: Are you still willing to work on this?


I am willing but time is lacking, and I'm already on my way to Lenexa. If you know how to workaround CWG1432 and want to move this patch forward quickly then don't let me hold it.


================
Comment at: include/type_traits:1453
@@ -1452,12 +1452,3 @@
 {
-private:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static _Tp&& __t();
-    static _Up&& __u();
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static _Tp __t();
-    static _Up __u();
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-public:
-    typedef typename remove_reference<decltype(true ? __t() : __u())>::type type;
+    typedef typename decay<decltype(true ? declval<_Tp>() : declval<_Up>())>::type type;
 };
----------------
EricWF wrote:
> Is it possible to make the non-variadic version SFINAE friendly as well? Or does it  require expression SFINAE (which ilslikely not available)?
The implementation used in the variadic version does indeed require expression SFINAE.

================
Comment at: include/type_traits:1478
@@ -1477,1 +1477,3 @@
+struct __common_type2<_Tp, _Up,
+    typename __void_t<decltype(true ? declval<_Tp>() : declval<_Up>())>::type>
 {
----------------
EricWF wrote:
> I think we need to qualify the `declval<Tp>` calls so they don't use ADL.
Good catch.

================
Comment at: include/type_traits:1501-1502
@@ -1491,1 +1500,4 @@
 
+template <class _Tp, class _Up, class ..._Vp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...>
+    : __common_type_impl<__common_types<_Tp, _Up, _Vp...> > {};
----------------
EricWF wrote:
> K-ballo wrote:
> > EricWF wrote:
> > > Isn't there a core language defect about the following specializations being ambiguous? Something along the lines of this? 
> > > 
> > > ```
> > > template <class ...> struct Foo;
> > > 
> > > template <class T> 
> > > struct Foo<T> {}; // Specialization 1
> > > 
> > > template <class T, class ... Args>
> > > struct Foo<T, Args...> {}; // Specialization 2
> > > 
> > > using MyFoo = Foo<int>; // The defect is that both 1 and 2 match.
> > > 
> > > ```
> > > 
> > > As far as I know it is accepted by all compilers but I just wanted to bring this up.
> > > 
> > I'm not sure, will investigate.
> I think I found the bug that tracks this: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1432 . Could we work around it for now?
I'm not sure I understand how to workaround this issue. Would that just take a third non-variadic argument, say `<_Tp, _Up, _Vp, Wp...>`?

http://reviews.llvm.org/D6964

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the cfe-commits mailing list