[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