[PATCH] [libc++] Try and prevent evaluation of `is_default_constructible` on tuples default constructor if it is not needed.
Louis Dionne
ldionne.2 at gmail.com
Thu Feb 12 07:34:12 PST 2015
In http://reviews.llvm.org/D7569#122353, @EricWF wrote:
> 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()`.
Let's take the `pair` example:
template <class T, class U>
struct pair {
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() {}
};
Because `T` and `U` are known when `pair<T, U>` is instantiated, regardless of
whether the default constructor is instantiated too, the above is equivalent to
template <class T, class U>
struct pair {
static constexpr bool T_is_default_constr = std::is_default_constructible<T>::value;
static constexpr bool U_is_default_constr = std::is_default_constructible<U>::value;
template <bool Dummy = true,
class = typename std::enable_if<
T_is_default_constr
&& U_is_default_constr
&& Dummy>::type
>
constexpr pair() {}
};
So Clang can (and does) instantiate the `is_default_constructible<T>` as soon
as it can, which is as soon as `pair<T, U>` is instantiated. What I wrote for
`std::tuple` would then just be equivalent to:
template <class ..._Tp>
struct tuple {
static constexpr bool _Tp1_is_default_constr = std::is_default_constructible<_Tp1>::value;
...
static constexpr bool _Tpn_is_default_constr = std::is_default_constructible<_Tpn>::value;
template <bool Dummy = true,
class = typename std::enable_if<
_Tp1_is_default_constr && Dummy
&& ...
&& _Tpn_is_default_constr && Dummy
>::type
>
constexpr pair() {}
};
At least, that's my analysis but I could be wrong.
> 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 a really good question. I think it could, in theory. That's because
a constructor does not have a name, so it is impossible to call e.g.
tuple<int, char>::tuple</* Dummy = */false>()
Hence, I think in theory the compiler could say "hey you have template
parameters but it is _impossible_ to specify something else than their
default value, so let's substitute the parameters now". I'm not sure
what is said about that in the standard though; perhaps someone can
shed light on this?
Louis
http://reviews.llvm.org/D7569
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the cfe-commits
mailing list