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.

Reply via email to