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.
I think you're right - so confirmed
Fixed for 4.7.0 by patch for PR 48449.