My understanding is that function arguments are always passed by reference whether prefixed with & or not. However, it seems that GCC gets confused when the two forms are mixed in a templated function declaration.
I somehow understand why it is stylistically unadvisable to mix the two forms but I don’t understand why it would not compile anyway.
what is the rationale?
In the attached code, fluke3 does not compile because the calling signature cannot be matched to one of the available templates. (error: no matching function for call to ‘fluke3(int (&)(int), int (&)(int))’)
My understanding is that function arguments are always passed by reference whether prefixed with & or not.
That's incorrect: you're confusing pointers and references. If you prefix a function argument with a &, the type of the argument is a pointer (to function), and that cannot be used with a reference parameter., as the compiler told you.
Simpler repro
1 2 3 4 5 6 7 8 9 10 11 12
using F = int(int); // function type
// this function takes a function by preference
int g(F& f) {
return f(1);
}
int dbl(int x) { return x*2; }
int main()
{
g(dbl); // OK (pass by reference)
g(&dbl); // Error: (function expects F&, but the argument is F*)
}
Thanks for your response but my question was about template resolution. I probably confused you by writing " whether prefixed with & or not". I just meant that if F is a function type, whether an argument is declared as F& foo or F foo doesn't matter, it will always be a reference.
Thanks for your reply, I do see that the problem is that the same template symbol can't be associated with both the
‘int (*)(int)’
and
‘int(int)’)
types.
However, as you point out, a function is always a pointer and there is never a value of type ‘int(int)’ (correct ?). Ultimately the reference type is substituted to the value type by the compiler (correct ?). So I had imagined that the substitution would also happen during template processing. Obviously, it is not the case. Perhaps, it is just the way it is because there is no real reason to do otherwise, perhaps the idea is just plain absurd, I am wondering.