请参阅下面的代码。 drive()
在范围内,我可以驾驶
保时捷
。然而,除非我取消注释 drive()
的声明,否则在尝试创建仿函数时,g++ 会给出一个非常奇怪的“drive” was not declared in this scope 错误。为什么?
#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:关于ADL的回答我已经基本满意了,但是我确实告诉了drive参数的类型,它是第一个模板参数,是car:
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
了。道理同上,只是这段代码没有被模板遮挡。
最佳答案
当您在一个类中声明一个具有非限定 id 的 friend
函数并且该函数不是另一个类的成员时,它会在最近的封闭非类、非函数原型(prototype)中命名一个函数范围。
如果之前没有声明该函数,则 friend
声明不会使该函数在该范围内可见。
但是,该函数对于参数相关查找是可见的。
在表达式 drive(porsche);
中,porsche
的类型为 car
,因此使用了 ADL 并且可以找到友元函数。
在表达式 drive
中没有参数,因此不执行 ADL。没有可见的 drive
声明,因此查找失败。
关于c++ - 创建仿函数时友元函数的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4777025/