http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54738
Bug #: 54738 Summary: [C++11][SFINAE] Hard errors for pointer-to-member function expressions Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: daniel.krueg...@googlemail.com During my attempts to implement sfinae-friendly result_of I found the following problems using gcc 4.8.0 20120923 (experimental) with compile-flags -Wall -pedantic -std=c++0x with pointer-to-member function expressions. First there are problems if we have an incompatible number of function call arguments: //--- template<class T> T&& declval(); template<class F, class T1, class... Ts> decltype(((*declval<T1>()).*declval<F>())(declval<Ts>()...)) test1(int); template<class...> void test1(...); template<class F, class T1, class... Ts> decltype((declval<T1>().*declval<F>())(declval<Ts>()...)) test2(int); template<class...> void test2(...); struct S {}; typedef void (S::*Func)(int) const; typedef decltype(test1<Func, S*>(0)) type1a; // #22 typedef decltype(test1<Func, S*&>(0)) type1b; typedef decltype(test1<Func, S*, int, int>(0)) type1c; typedef decltype(test1<Func, S*&, int, int>(0)) type1d; typedef decltype(test2<Func, S>(0)) type2a; // #27 typedef decltype(test2<Func, S&>(0)) type2b; typedef decltype(test2<Func, S, int, int>(0)) type2c; typedef decltype(test2<Func, S&, int, int>(0)) type2d; //--- The error messages are: <quote> 22| required from here| 6|error: too few arguments to function| 22| required from here| 6|error: too few arguments to function| 23| required from here| 6|error: too few arguments to function| 23| required from here| 6|error: too few arguments to function| 24| required from here| 6|error: too many arguments to function| 25| required from here| 6|error: too many arguments to function| 27| required from here| 13|error: too few arguments to function| 27| required from here| 13|error: too few arguments to function| 28| required from here| 13|error: too few arguments to function| 28| required from here| 13|error: too few arguments to function| 29| required from here| 13|error: too many arguments to function| 30| required from here| 13|error: too many arguments to function| </quote> Further there are also problems with corresponding function call expressions where the arguments won't convert: //--- template<class T> T&& declval(); template<class F, class T1, class... Ts> decltype(((*declval<T1>()).*declval<F>())(declval<Ts>()...)) test1(int); template<class...> void test1(...); template<class F, class T1, class... Ts> decltype((declval<T1>().*declval<F>())(declval<Ts>()...)) test2(int); template<class...> void test2(...); struct S {}; typedef void (S::*Func)(int) const; typedef decltype(test1<Func, S*, S>(0)) type3a; // #22 typedef decltype(test1<Func, S*&, S>(0)) type3b; typedef decltype(test2<Func, S, S>(0)) type4a; // #25 typedef decltype(test2<Func, S&, S>(0)) type4b; //--- The error messages are: <quote> 22| required from here| 6|error: cannot convert 'S' to 'int' in argument passing| 22| required from here| 6|error: cannot convert 'S' to 'int' in argument passing| 23| required from here| 6|error: cannot convert 'S' to 'int' in argument passing| 23| required from here| 6|error: cannot convert 'S' to 'int' in argument passing| 25| required from here| 13|error: cannot convert 'S' to 'int' in argument passing| 25| required from here| 13|error: cannot convert 'S' to 'int' in argument passing| 26| required from here| 13|error: cannot convert 'S' to 'int' in argument passing| 26| required from here| 13|error: cannot convert 'S' to 'int' in argument passing| </quote> Further cv-violations aren't sfinaed away: //--- template<class T> T&& declval(); template<class F, class T1, class... Ts> decltype(((*declval<T1>()).*declval<F>())(declval<Ts>()...)) test1(int); template<class...> void test1(...); template<class F, class T1, class... Ts> decltype((declval<T1>().*declval<F>())(declval<Ts>()...)) test2(int); template<class...> void test2(...); struct S {}; typedef void (S::*Func2)(int); typedef decltype(test1<Func2, const S*, int>(0)) type5a; // #22 typedef decltype(test1<Func2, const S*&, int>(0)) type5b; typedef decltype(test2<Func2, const S, int>(0)) type6a; // #25 typedef decltype(test2<Func2, const S&, int>(0)) type6b; //--- The error messages are: <quote> 22| required from here| 6|error: invalid conversion from 'const S*' to 'S*' [-fpermissive]| 23| required from here| 6|error: invalid conversion from 'const S*' to 'S*' [-fpermissive]| 25| required from here| 13|error: invalid conversion from 'const S*' to 'S*' [-fpermissive]| 26| required from here| 13|error: invalid conversion from 'const S*' to 'S*' [-fpermissive]| </quote> These code examples should all be accepted.