Reputation: 66230
Another "who's right between g++ and clang++?" question for C++ standard gurus.
The following program
#include <iostream>
void foo (int v)
{ std::cout << "foo(), int version (" << v << ')' << std::endl; }
void foo (double v)
{ std::cout << "foo(), double version (" << v << ')' << std::endl; }
template <typename T, typename R>
void bar (T v, R(*fn)(T))
{ fn(v); }
int main ()
{ bar(1, foo); }
compile and run with g++ (6.3.0, but also with 8.0.0 according Wandbox) but compiling it with clang++ (3.9.1, but also with 6.0.0 according Wandbox) I get the following error
tmp_002-11,14,gcc,clang.cpp:29:4: error: no matching function for call to 'bar'
{ bar(1, foo); }
^~~
tmp_002-11,14,gcc,clang.cpp:25:6: note: candidate template ignored: couldn't
infer template argument 'R'
void bar (T v, R(*fn)(T))
^
1 error generated.
As usual the question is: who's right? g++ or clang++?
Upvotes: 10
Views: 235
Reputation: 40023
Clang is correct, but for a subtle reason: an overload set is allowed during template deduction, but deduction on that one argument must be able to select one of them for anything to be deduced. (If zero match, the overall deduction fails; if more than one does, deduction ignores that argument.) Here, both foo
s match R(*fn)(T)
, so R
cannot be deduced from that argument (even though they would both agree on it), and thus not at all.
Upvotes: 1