See the code below. The drive() is in the scope, I can drive the porsche. However, unless I uncomment the declaration of drive(), g++ gives a very weird ‘drive’ was not declared in this scope error when trying to create the functor. Why?
#include <functional>
class car {
friend void drive(const car c);
};
//void drive(const car c);
int main() {
car porsche;
drive(porsche);
std::pointer_to_unary_function<car, void> functor(drive);
return 0;
}
UPDATE 1: I am almost satified with the answer concerning ADL, however I did tell the type of the argument of drive, it is the first template parameter, it is car:
std::pointer_to_unary_function<car, void> functor(drive);
UPDATE 2: OK, here is an even simpler code, we do not need the functor and the functional header:
class car {
friend void drive(const car c);
};
//void drive(const car c) { }
int main() {
car porsche;
drive(porsche);
void (*f)(const car);
f = drive;
return 0;
}
Now, I understand why the compiler cannot find drive with ADL. The reason is the same as above, but this code is not obscured by the template.
When you declare a
friendfunction with an unqualified id in a class and that function is not a member of another class, it names a function in the nearest enclosing non-class, non-function prototype scope.If that function hasn’t previously been declared then the
frienddeclaration doesn’t make that function visible in that scope.However, that function is visible for argument dependent lookup.
In the expression
drive(porsche);, theporschehas typecarso ADL is used and the friend function can be found.In the expression
drivethere are no arguments so ADL is not performed. There is no declaration ofdrivevisible so the lookup fails.