【问题标题】:visibility of friend functions when creating functors创建函子时友元函数的可见性
【发布时间】:2011-06-14 04:53:55
【问题描述】:

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

更新 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。原因同上,只是这段代码没有被模板遮挡。

【问题讨论】:

标签: c++ scope visibility friend functor


【解决方案1】:

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

如果该函数之前未声明过,那么 friend 声明不会使该函数在该范围内可见。

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

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

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

【讨论】:

  • @Ali:你认为编译器为什么能找到drive?如果它没有为 drive 执行 ADL(不是因为它不是函数调用表达式),则 drive 没有可见的声明。
  • 好的,我会详细了解 ADL 是什么。我认为从您的回答中推断出参数类型就足够了。
  • @Ali:我不明白你的意思。您指定模板的所有参数,不需要或可能的参数推导。问题是名称 drive 在任何非 ADL 查找中都不可见。
  • 请给我一些时间来了解 ADL 到底是什么。从您的回答看来,在我看来推断类型就足够了。感谢您的回答和耐心等待!
【解决方案2】:

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

【讨论】:

  • 如果它没有声明一个函数那我怎么开保时捷呢?
  • 如果你想把驱动作为一个全局函数(尽管通常人们做的是类成员函数),那么你只需要定义驱动函数。定义它的一种方法是:class car {friend void drive(const car c) {write something here;}};另一种定义它的方法是在全局级别:void drive(const car c) {write something here;}。朋友 void drive(const car c);本身没有定义函数。它几乎没有说如果存在这样的函数,它就是那个类的朋友。
  • 朋友是否声明了一个函数。
猜你喜欢
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 2014-06-23
  • 1970-01-01
  • 2014-07-14
相关资源
最近更新 更多