public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/93923] [10 Regression] std::is_copy_constructible raises compilation error
       [not found] <bug-93923-4@http.gcc.gnu.org/bugzilla/>
@ 2020-03-18 23:55 ` redi at gcc dot gnu.org
  0 siblings, 0 replies; only message in thread
From: redi at gcc dot gnu.org @ 2020-03-18 23:55 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-18 23:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <bug-93923-4@http.gcc.gnu.org/bugzilla/>
2020-03-18 23:55 ` [Bug libstdc++/93923] [10 Regression] std::is_copy_constructible raises compilation error redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).