[Bug libstdc++/93923] [10 Regression] std::is_copy_constructible raises compilation error

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Mar 18 23:55:05 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93923

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I'm going to close this, for the reason stated earlier: the standard says you
can't use is_constructible with an incomplete type.

Performing overload resolution for is_copy_constructible<A> has to check if
A(const B<A>&) is viable, which tries to construct B<A> from const A&, which
has to check the constraints of B<A>::B(Args&&...) which depends on
is_constructible<A, const A&>.

I'm not convinced this example is very realistic, but if needed it can be fixed
by excluding the B(Args&&...) constructor from being used with a single
argument of type T:

template<typename T>
struct  B {
    template<class T1, class... Args>
      struct check : std::is_constructible<T1, Args...> { };
    template<class T1, class Arg1>
      struct check<T1, Arg1> : std::is_same<T1, std::decay_t<Arg1>> { };

    template<
        class... Args,
        std::enable_if_t<check<T, Args...>::value, int> = 0>
    B(Args && ... args) {}

    B(const T&) { }
    B(T&&) { }
};

Alternatively, just make the B(Args&&...) constructor explicit (and add a
separate default constructor, because explicit default constructors are weird
and unhelpful), which is probably the right thing to do anyway:

template<typename T>
struct  B {
    template<
        class... Args,
        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0 >
    explicit
    B(Args && ... args) {}

    B() = default;
};

If you have a realistic use case that can't be solved in one of these ways, and
shows a reasonable situation where is_constructible needs to work for
incomplete types, please provide it and re-open the bug.


More information about the Gcc-bugs mailing list