创建仿函数时,友元函数的可见性

Ali*_*Ali 1 c++ visibility scope friend functor

请参阅下面的代码.该drive() 是在范围内,我可以driveporsche.但是,除非我取消注释声明,否则drive()g ++会在尝试创建仿函数时在此范围错误中声明一个非常奇怪的"驱动器".为什么?

#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;
}
Run Code Online (Sandbox Code Playgroud)

更新1:我对ADL的答案几乎感到满意,但是我确实告诉了驱动器参数的类型,它是第一个模板参数,它是汽车:

std::pointer_to_unary_function<car, void> functor(drive);
Run Code Online (Sandbox Code Playgroud)

更新2:好的,这是一个更简单的代码,我们不需要函子和函数头:

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;
}
Run Code Online (Sandbox Code Playgroud)

现在,我理解为什么编译器无法找到driveADL.原因与上面相同,但此代码不会被模板遮盖.

CB *_*ley 5

当您friend在类中声明具有非限定id的函数并且该函数不是另一个类的成员时,它会在最近的封闭非类非函数原型范围中命名函数.

如果先前未声明该函数,则friend声明不会使该函数在该范围内可见.

但是,该函数对于参数依赖查找是可见的.

在表达式中drive(porsche);,使用了porsche类型,car因此可以使用ADL并找到友元函数.

在表达式drive中没有参数,因此不执行ADL.没有drive可见的声明,因此查找失败.