Ill-formed C++0x code or compiler bug (GCC) ?
 
Hi!
In the following C++0x code I tried to clone an object by using a
clone member function (if it exists) and falling back on a copy
constructor:
   #include <type_traits>
   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;
   }
The idea is to use auto...->decltype(expr) to weed out ill-formed
expressions as part of the template argument deduction (SFINAE) and to
resolve a possible ambiguity between both clone function templates via
partial ordering w.r.t. the second function parameter.
Unfortunately, GCC 4.5.1 doesn't accept this program:
test.cpp: In function 'int main()':
test.cpp:30:39: error: cannot allocate an object of abstract type
'abc'
test.cpp:16:12: note:   because the following virtual functions are
pure within 'abc':
test.cpp:18:16: note:        virtual abc* abc::clone() const
test.cpp:30:39: error: cannot allocate an object of abstract type
'abc'
test.cpp:16:12: note:   since type 'abc' has pure virtual functions
Now, the question is, is this a compiler bug or was I wrong to assume
that SFINAE applies here?
Cheers!
SG