Understanding how the compiler resolves function pointers

The following code snippet:

#include <iostream> void does() { std::cout << "do" << std::endl; } void does(bool b = false) { std::cout << "do(bool)" << std::endl; } void fwd(void (*func)(bool)) { func(false); } int main(int, char**) { fwd(&does); fwd(does); fwd(*does); } 

clearly causes the following error:

test.cpp:15:10: error: overloaded function with no contextual type information

The compiler cannot determine which of the functions I intend to use. I don’t understand why the code will work correctly when I comment out a line that says:

fwd(*does)

Why can the compiler suddenly solve the ambiguity problem?

 int main(int, char**) { fwd(&does); fwd(does); } 

In addition, without overloading, the fragment will start correctly with all 3 calls. This snippet works great ...

 #include <iostream> void does(bool b = false) { std::cout << "do(bool)" << std::endl; } void fwd(void (*func)(bool)) { func(false); } int main(int, char**) { fwd(&does); fwd(does); fwd(*does); } 

I am compiling this with gcc 4.6.3 in a Linux box.

Thanks for the help!

+7
c ++ function function-pointers
source share
2 answers

The answer to your question is overload rules for functions.
In particular, there is an exception for using & in front of a function name (once) that does not violate overload permission, but not for using * .
Also make sure that only one of these two functions accepts this single argument:

13.4 Address of the overloaded function [over.over]

1 Using an overloaded function name without arguments is permitted in certain contexts of a function, a function pointer, or a member function pointer for a specific function from the overload set. The name of the function template is considered the named set of overloaded functions in such contexts. The selected function is a type identical to the type of the function of the target type required in the context. [Note. That is, the class of which the member is a member is ignored when matching type-pointer-member-function. -end note] The target may be

  • the object or reference is initialized (8.5, 8.5.3),
  • left part of the task (5.17),
  • function parameter (5.2.2),
  • user operator parameter (13.5),
  • return value of a function, operator function or transformation (6.6.3),
  • explicit type conversion (5.2.3, 5.2.9, 5.4) or
  • asymmetric template parameter (14.3.2).

An overloaded function name may be preceded by the & operator. An overloaded function name should not be used without arguments in contexts other than those listed.

Quote from n3242 (C ++ 11), which I have highlighted.

+7
source share

fwd expects a function that takes a boolean parameter; you only have one such version of does , so there is no confusion. In fact, does and &does are considered the same (since functions cannot be values, one of these two should be technically incorrect, if not impossible to imagine, but the language should be chosen instead, and just treat them as one and the same).

But when you try to use fwd(*does) , you need a definition of does that will be divided into such a function, and you have nothing of the kind - in fact, since I was trained recently, you cannot have anything like that.

0
source share

All Articles