public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/51336] New: [C++11] is_abstract and sfinae
@ 2011-11-28 19:30 marc.glisse at normalesup dot org
  2011-11-28 21:05 ` [Bug c++/51336] " daniel.kruegler at googlemail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: marc.glisse at normalesup dot org @ 2011-11-28 19:30 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

             Bug #: 51336
           Summary: [C++11] is_abstract and sfinae
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: marc.glisse@normalesup.org


#include <type_traits>
template<class T>
struct A {
        template<class=typename
std::enable_if<std::is_same<T,int>::value>::type>
                A(A const&){}
};
constexpr bool b = std::is_abstract<A<double>>::value;

$ g++ -std=c++0x n.cc -c
n.cc: In instantiation of 'struct A<double>':
/tmp/gcc/inst/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/type_traits:530:12:
  required from 'struct std::is_abstract<A<double> >'
n.cc:7:47:   required from here
n.cc:5:3: error: no type named 'type' in 'struct std::enable_if<false, void>'

I am not sure what is supposed to happen (that's why I tried), but this result
doesn't seem right. Filed under C++ because is_abstract directly forwards to
the __is_abstract builtin, but feel free to reassign to libstdc++ if you think
the problem is there somehow.

I first tried it with is_copy_constructible (which indirectly calls is_abstract
through is_destructible) to check the value it would give (clang+libc++ says
is_copy_constructible is true).


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
@ 2011-11-28 21:05 ` daniel.kruegler at googlemail dot com
  2011-11-28 21:49 ` marc.glisse at normalesup dot org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-11-28 21:05 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

Daniel Krügler <daniel.kruegler at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.kruegler at
                   |                            |googlemail dot com

--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-11-28 20:49:52 UTC ---
(In reply to comment #0)
> #include <type_traits>
> template<class T>
> struct A {
>         template<class=typename
> std::enable_if<std::is_same<T,int>::value>::type>
>                 A(A const&){}
> };
> constexpr bool b = std::is_abstract<A<double>>::value;

I *think* the compiler is right to reject this as it currently does, we have
*no* sfinae here. When you instantiate A<double>, the declaration of the
template constructor is also instantiated, but at that point A<double> is an
incomplete type.

IMO you need one further indirection, e.g.

template<class T>
struct A {
  template<class U = T, class = typename
    std::enable_if<std::is_same<U, int>::value>::type
  >
  A(A const&){}
};

Btw.: Neither of these forms can ever prevent the "real" copy constructor to be
declared, defined, and used by the compiler.

> I am not sure what is supposed to happen (that's why I tried), but this result
> doesn't seem right. Filed under C++ because is_abstract directly forwards to
> the __is_abstract builtin, but feel free to reassign to libstdc++ if you think
> the problem is there somehow.

Lets look what the compiler-intrinsic people say, above is my first guess on
that.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
  2011-11-28 21:05 ` [Bug c++/51336] " daniel.kruegler at googlemail dot com
@ 2011-11-28 21:49 ` marc.glisse at normalesup dot org
  2011-11-29  8:49 ` daniel.kruegler at googlemail dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: marc.glisse at normalesup dot org @ 2011-11-28 21:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #2 from Marc Glisse <marc.glisse at normalesup dot org> 2011-11-28 21:17:30 UTC ---
(In reply to comment #1)
> IMO you need one further indirection, e.g.

Ah, yes, makes sense (although clang accepts both versions).

> Btw.: Neither of these forms can ever prevent the "real" copy constructor to be
> declared, defined, and used by the compiler.

I was experimenting with it because I don't understand why this code (your
fixed version) is valid if that declaration has no effect... (well, it does
remove the implicit A(), but that doesn't count)

Maybe I should ask for a warning?


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
  2011-11-28 21:05 ` [Bug c++/51336] " daniel.kruegler at googlemail dot com
  2011-11-28 21:49 ` marc.glisse at normalesup dot org
@ 2011-11-29  8:49 ` daniel.kruegler at googlemail dot com
  2011-11-29 10:29 ` paolo.carlini at oracle dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-11-29  8:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #3 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-11-29 07:08:45 UTC ---
(In reply to comment #1)
> When you instantiate A<double>, the declaration of the template constructor is 
> also instantiated, but at that point A<double> is an incomplete type.

I just recognize that the last part of this is a bit misleading, please read
this as:

"When you instantiate A<double>, the declaration of the template constructor is 
also instantiated, but this turns out to be an ill-formed signature"

The argument in regard to type-completeness was intended to point to the
library specification, which requires A<double> to be complete, which means
that A<double> may be instantiated including it's member declarations, which
again is the cause of the error, because we have no sfinae situation here.

In regard to the __is_abstract builtin question it seems that in simple cases
like these (no dependent base classes involved), it may be possible to
implement the intrinsic without instantiating A<double>, but maybe the current
behavior is actually better, because it makes portable programming easier;-)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (2 preceding siblings ...)
  2011-11-29  8:49 ` daniel.kruegler at googlemail dot com
@ 2011-11-29 10:29 ` paolo.carlini at oracle dot com
  2011-11-29 10:36 ` marc.glisse at normalesup dot org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-11-29 10:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #4 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-11-29 10:11:34 UTC ---
The issue with type_traits intrinsics vs instantiation came up recently, when I
fixed an actual bug affecting __is_base_of. Note, if isn't clear already, that
in the case of is_abstract, C++11 requires unconditionally completeness for T:
we are treating all the traits having such type of precondition in an uniform
way. All in all, I agree with Daniel about portability.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (3 preceding siblings ...)
  2011-11-29 10:29 ` paolo.carlini at oracle dot com
@ 2011-11-29 10:36 ` marc.glisse at normalesup dot org
  2011-11-29 10:51 ` marc.glisse at normalesup dot org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: marc.glisse at normalesup dot org @ 2011-11-29 10:36 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #5 from Marc Glisse <marc.glisse at normalesup dot org> 2011-11-29 10:27:18 UTC ---
All right, now the is_abstract behavior is settled, do you think the fixed code
provided by Daniel in comment #1 should produce a warning, since the
declaration is absolutely useless (I may be missing something)? Or maybe there
are legitimate meta-programming tricks I am not thinking of that would turn
regular constructors into pseudo copy constructors to disable them?


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (4 preceding siblings ...)
  2011-11-29 10:36 ` marc.glisse at normalesup dot org
@ 2011-11-29 10:51 ` marc.glisse at normalesup dot org
  2011-11-29 11:26 ` daniel.kruegler at googlemail dot com
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: marc.glisse at normalesup dot org @ 2011-11-29 10:51 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

Marc Glisse <marc.glisse at normalesup dot org> changed:

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

--- Comment #6 from Marc Glisse <marc.glisse at normalesup dot org> 2011-11-29 10:34:08 UTC ---
(In reply to comment #5)
> All right, now the is_abstract behavior is settled, do you think the fixed code
> provided by Daniel in comment #1 should produce a warning, since the
> declaration is absolutely useless (I may be missing something)?

Ah, I did find a case where it was used:
I added a A(A&) constructor to prevent the default A(A const&) from being
generated, and then the template version was used when copying from const (only
if T is int).

Closing the bug as invalid, thanks for your answers.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (5 preceding siblings ...)
  2011-11-29 10:51 ` marc.glisse at normalesup dot org
@ 2011-11-29 11:26 ` daniel.kruegler at googlemail dot com
  2011-11-29 12:02 ` marc.glisse at normalesup dot org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-11-29 11:26 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #7 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-11-29 10:50:37 UTC ---
(In reply to comment #5)
> All right, now the is_abstract behavior is settled, do you think the fixed code
> provided by Daniel in comment #1 should produce a warning, since the
> declaration is absolutely useless (I may be missing something)? 

IMO a warning could be very useful here (at least in circumstances where the
constructor is never reachable).

> Or maybe there are legitimate meta-programming tricks I am not thinking of that 
> would turn regular constructors into pseudo copy constructors to disable them?

While it seems that the current defect in regard to concept-constrained member
functions mentioned in c++std-core-20783 is a defect, so that

template<ObjectType T>
class A {
 requires SomeConcept<T>
 A(const A&) {}
};

is *intended* to work, I currently see no such chance for sfinae-constrained
special-member functions - unless the new temploid nomenclature shows that in

template<class T>
struct A {
  template<class U = T, class = typename
    std::enable_if<std::is_same<U, int>::value>::type
  >
  A(A const&){}
};

A<T>::A(A const&) is considered as a temploid as well. I stay tuned to see how
"temploids" will be defined...

Your suggested addition of a copy-constructor to non-const is surely useful in
some cases, but I think the emulation is imperfect. Just consider that you try
to copy from a source that is not const.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (6 preceding siblings ...)
  2011-11-29 11:26 ` daniel.kruegler at googlemail dot com
@ 2011-11-29 12:02 ` marc.glisse at normalesup dot org
  2011-11-29 13:00 ` daniel.kruegler at googlemail dot com
  2022-02-17 10:41 ` [Bug c++/51336] [C++11] warn on inaccessible template special member functions redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: marc.glisse at normalesup dot org @ 2011-11-29 12:02 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

Marc Glisse <marc.glisse at normalesup dot org> changed:

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

--- Comment #8 from Marc Glisse <marc.glisse at normalesup dot org> 2011-11-29 11:26:19 UTC ---
(In reply to comment #7)
> IMO a warning could be very useful here (at least in circumstances where the
> constructor is never reachable).

Ok, reopening then. Not sure how easy it is to test for reachability in
general, but there are certainly easy cases where it is doable.

> While it seems that the current defect in regard to concept-constrained member
> functions mentioned in c++std-core-20783 is a defect, so that
> 
> template<ObjectType T>
> class A {
>  requires SomeConcept<T>
>  A(const A&) {}
> };
> 
> is *intended* to work,

That would be great. I assume that when T doesn't satisfy SomeConcept, the
compiler can still generate a default copy constructor (we can always have a
deleted copy constructor with requires !SomeConcept<T> if we don't want it).

> I currently see no such chance for sfinae-constrained
> special-member functions - unless the new temploid nomenclature shows that in
> 
> template<class T>
> struct A {
>   template<class U = T, class = typename
>     std::enable_if<std::is_same<U, int>::value>::type
>   >
>   A(A const&){}
> };
> 
> A<T>::A(A const&) is considered as a temploid as well. I stay tuned to see how
> "temploids" will be defined...

Looks interesting, although since we're talking about a future standard (at
least I assume that's what you are talking about? Or are temploids coming up as
a bugfix for C++11?), I'd rather write (see around c++std-ext-11764):
static if(std::is_same<T,int>())
A(A const&){ /* special code */ }

> Your suggested addition of a copy-constructor to non-const is surely useful in
> some cases, but I think the emulation is imperfect. Just consider that you try
> to copy from a source that is not const.

I completely agree, I was just trying to see if there was any possibility for
the templated "copy" constructor to have any effect (not even necessarily a
useful one). If there had been none, a warning was definitely warranted.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] is_abstract and sfinae
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (7 preceding siblings ...)
  2011-11-29 12:02 ` marc.glisse at normalesup dot org
@ 2011-11-29 13:00 ` daniel.kruegler at googlemail dot com
  2022-02-17 10:41 ` [Bug c++/51336] [C++11] warn on inaccessible template special member functions redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-11-29 13:00 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51336

--- Comment #9 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-11-29 11:36:34 UTC ---
(In reply to comment #8)
> Looks interesting, although since we're talking about a future standard (at
> least I assume that's what you are talking about? Or are temploids coming up as
> a bugfix for C++11?)

The term "temploid" will very probably be introduced for C++11 already, we have
a lot of core issues that could be resolved much easier with that concept (I'm
not referring here to language-concepts, just to make that clear).


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/51336] [C++11] warn on inaccessible template special member functions
  2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
                   ` (8 preceding siblings ...)
  2011-11-29 13:00 ` daniel.kruegler at googlemail dot com
@ 2022-02-17 10:41 ` redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2022-02-17 10:41 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The name temploid got replaced by "templated entity", see [temp.pre].

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-02-17 10:41 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-28 19:30 [Bug c++/51336] New: [C++11] is_abstract and sfinae marc.glisse at normalesup dot org
2011-11-28 21:05 ` [Bug c++/51336] " daniel.kruegler at googlemail dot com
2011-11-28 21:49 ` marc.glisse at normalesup dot org
2011-11-29  8:49 ` daniel.kruegler at googlemail dot com
2011-11-29 10:29 ` paolo.carlini at oracle dot com
2011-11-29 10:36 ` marc.glisse at normalesup dot org
2011-11-29 10:51 ` marc.glisse at normalesup dot org
2011-11-29 11:26 ` daniel.kruegler at googlemail dot com
2011-11-29 12:02 ` marc.glisse at normalesup dot org
2011-11-29 13:00 ` daniel.kruegler at googlemail dot com
2022-02-17 10:41 ` [Bug c++/51336] [C++11] warn on inaccessible template special member functions 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).