[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...);

and

  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
handle.

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