Bug 47513 - [C++0x] [SFINAE] compiler rejects valid code
Summary: [C++0x] [SFINAE] compiler rejects valid code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.1
: P3 normal
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2011-01-28 12:44 UTC by Sebastian Gesemann
Modified: 2011-04-08 15:22 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-28 14:43:43


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Gesemann 2011-01-28 12:44:28 UTC
I believe the following code should compile using the option -std=c++0x:

   struct use_copy_ctor {};
   struct prefer_clone_func : use_copy_ctor {};

   template<class T>
   auto clone(T const* ptr, prefer_clone_func)
   -> decltype(ptr->clone())
   { return ptr->clone(); }

   template<class T>
   auto clone(T const* ptr, use_copy_ctor)
   -> decltype(new T(*ptr))
   { return new T(*ptr); }

   struct abc {
     virtual ~abc() {}
     virtual abc* clone() const =0;
   };

   struct derived : abc
   {
     derived* clone() const { return new derived(*this); }
   };

   int main()
   {
     derived d;
     abc* p = &d;
     abc* q = clone(p,prefer_clone_func());
     delete q;
   }

As far as I can tell SFINAE applies during template argument deduction where abc is substituted for T in decltype(new T(*ptr)). GCC complains about abc being abstract -- which it is, of course -- but it should instead simply ignore the second function template.

Related note: Assuming std::is_constructible is implemented in terms of decltype, this would explain why std::is_constructible doesn't work either on abstract class types.
Comment 1 Jonathan Wakely 2011-01-28 14:43:43 UTC
I think you're right - so confirmed
Comment 2 Jason Merrill 2011-04-08 15:22:20 UTC
Fixed for 4.7.0 by patch for PR 48449.