[cfe-dev] libcxx: std::is_constructible only allows implicit conversion for scalar and reference types. Bug?

Richard Smith richard at metafoo.co.uk
Thu Nov 20 21:37:39 PST 2014

On Tue, Nov 18, 2014 at 2:21 AM, <sebastian at theophil.net> wrote:

> Hi,
> I recently filed http://llvm.org/bugs/show_bug.cgi?id=21574 because I
> think the library implementation of std::is_constructible is broken.
> For a type
> struct S {
>     template <typename T> explicit operator T() const;
>     explicit operator int const&() const;
> };
> both std::is_constructible< int, S > and std::is_constructible< int
> const&, S > report false despite the explicit cast operators and  although
> T t;
> int const& i1(t);
> int i2(t);
> compile fine.
> What was the rationale for specializing std::is_constructible for scalar
> and reference types at all? Without this entire special-cased branch,
> std::is_constructible<S, Args...> simply forwards to the SFINAE expression
> decltype(std::move(S(std::declval<Args>()...))). Isn't that what should
> always be evaluated because it tests that S(Args...) is a valid expression,
> just like the standard demands?

That's not quite what the standard demands;

  T t(args...);



are not valid in the same set of circumstances. In particular, they can
differ when args contains exactly one expression (or zero). T(arg) is
equivalent to (T)arg, which can perform a superset of the conversions
performed by T t(arg), and I would imagine this is what libc++ is trying to

I think that something like:

  decltype(::new S(std::declval<Args>()...))

... would cover all cases other than when S is a reference type.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141120/06f68d1c/attachment.html>

More information about the cfe-dev mailing list