c++ - 创建仿函数时友元函数的可见性

标签 c++ scope visibility friend functor

请参阅下面的代码。 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/

相关文章:

c++ - 将 int 转换为 std::string

python - 您可以分配给父函数中定义的变量吗?

c++ - 为什么要按照前置增量来实现后置增量呢?

c++ - 字符串变量的简单错误

java - 当变量超出范围时,它永远不能回到范围内

c - C 中函数参数的范围

WPF - 隐藏列表框项目

rust - 源特征不可访问

Xcode:如何将我的 .app 项目构建为共享库?

c++ - 在基类的非虚函数中调用基类的虚函数