[PATCH] [libc++] Try and prevent evaluation of `is_default_constructible` on tuples default constructor if it is not needed.

Richard Smith richard at metafoo.co.uk
Thu Feb 12 17:06:23 PST 2015


On Wed, Feb 11, 2015 at 6:34 PM, Eric Fiselier <eric at efcs.ca> wrote:

> >It's not yet completely clear whether Clang's (and GCC's) behavior is
> right here; there's an active core issue on how to handle this case.
>
> GCC 4.8 and clang actually do the exact same thing on the example
> code.


Right, that's why I said "(and GCC's)". =) EDG doesn't behave this way,
FWIW.


> What behavior are you referring to exactly?
>

The eager instantiation of the constexpr constructor that is used in an
unevaluated operand.

Could you explain why the dependent type trick actually works? I'm
> unsure as to why clang thinks it can evaluate one set of template
> arguments but not the other even though it has essentially the same
> information when evaluating `tuple()`.
>

Substituting into

  template <bool Dummy = true,
    class = typename std::enable_if<
         std::is_default_constructible<T>::value
      && std::is_default_constructible<U>::value
      && Dummy>::type
    >
  constexpr pair()

produces

  template <bool Dummy = true,
    class = typename std::enable_if<
         std::is_default_constructible<IllFormedDefaultImp>::value
      && std::is_default_constructible<IllFormedDefaultImp>::value
      && Dummy>::type
    >
  constexpr pair()

Note that this triggers the instantiation of
std::is_default_constructible<IllFormedDefaultImp>,
even though it appears within a value-dependent expression.

Both your and my rewrite avoid this by hiding the instantiation behind
another template that has a dependent argument.

Also is clang ever going to outsmart this trick and realize
> `dependent<is_default_constructible<_Tp>, Dummy>` is not actually
> dependent on anything in this context? (ie on a default constructor)
>

That's very unlikely; we'd have to use the fact that this is a constructor
to show that 'Dummy' is always 'true', and then use that to determine that
there are no valid specializations of the constructor template. It's not
even clear that this would be permissible under the guise of the "a
template that has no valid specializations is ill-formed" rule. Plus this
would break lots of real-world code, so we wouldn't do it even if we could.

Thanks for your input
>
> /Eric
>
>
>
>
>
> On Wed, Feb 11, 2015 at 7:12 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
> > ================
> > Comment at: include/type_traits:2649-2652
> > @@ -2648,1 +2648,6 @@
> >
> > +template <class _Tp, bool>
> > +struct _LIBCPP_TYPE_VIS_ONLY __dependent_is_default_constructible
> > +    : public is_default_constructible<_Tp>
> > +    {};
> > +
> > ----------------
> > Is it worth generalizing / simpilfying this:
> >
> >     template <class _Tp, bool> struct __dependent : public _Tp {};
> >
> > (Usage: `__dependent<is_default_constructible<_Tp>, Dummy>::value`)
> >
> > http://reviews.llvm.org/D7569
> >
> > EMAIL PREFERENCES
> >   http://reviews.llvm.org/settings/panel/emailpreferences/
> >
> >
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150212/466afb6a/attachment.html>


More information about the cfe-commits mailing list