Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deduce of argument of type class method (overloads by const qualifier) fails with trailing return type in gcc, but not in clang

Nothing clearer than an old good MCVE:

struct X {
  auto get(int) const -> int { return {}; }
  auto get(int) -> int { return {}; }
};

template <class R> auto f(auto (X::*)(int) const -> R) {}
//                        ^~~~                   ~~~~
//                        trailing return type

int main() {
  f(&X::get);
}

This fails in g++ (4.9.2 & 5.1.0). However if the old return type is used:

template <class R> auto f(R (X::*)(int) const) {}
//                        ^
//                        old return type

it works.

On clang (3.5.0) both variants work.

I know that trailing return type changes when the return type is inferred and the scope of it, so I wouldn't be quick to cast it as a gcc bug. So what does the standard says? Which compiler is right?


The most significant message in the error I think is

couldn't deduce template parameter ‘R’`

g++ full message:

main2.cpp: In function ‘int main()’:
main2.cpp:21:12: error: no matching function for call to ‘f(<unresolved overloaded function type>)’
   f(&X::get);
            ^
main2.cpp:18:25: note: candidate: template<class R, class auto:1> auto f(auto:1 (X::*)(int) const)
 template <class R> auto f(auto (X::*)(int) const -> R) {}
                         ^
main2.cpp:18:25: note:   template argument deduction/substitution failed:
main2.cpp:21:12: note:   types ‘auto:1 (X::)(int) const’ and ‘int (X::)(int)’ have incompatible cv-qualifiers
   f(&X::get);
            ^
main2.cpp:21:12: note:   couldn't deduce template parameter ‘R’
<builtin>: recipe for target 'main2' failed
make: *** [main2] Error 1
like image 260
bolov Avatar asked Nov 09 '22 09:11

bolov


1 Answers

As pointed in the question this is a gcc bug which was beed fixed in version 6

gcc.gnu.org/bugzilla/show_bug.cgi?id=69139

like image 102
bolov Avatar answered Nov 15 '22 06:11

bolov