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

时间:2011-01-23 22:34:35

标签: c++ scope visibility friend functor

请参阅下面的代码。 drive() 在范围内,我可以drive porsche。但是,除非我取消注释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;
}

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

std::pointer_to_unary_function<car, void> functor(drive);

更新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;
}

现在,我理解为什么编译器无法使用ADL找到drive。原因与上面相同,但模板不会掩盖此代码。

2 个答案:

答案 0 :(得分:5)

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

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

但是,该函数对参数相关的查找是可见的。

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

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

答案 1 :(得分:0)

因为朋友没有声明一个函数,而你正试图调用一个不存在的全局函数。