c – 与extern“C”函数的友谊似乎要求::限定名称

尝试使用一个extern“C”函数一个类的朋友,这段代码的作用是:
#include <iostream>

extern "C" {
  void foo();
}

namespace {
  struct bar {
    // without :: this refuses to compile
    friend void ::foo();
    bar() : v(666) {}
  private:
    int v;
  } inst;
}

int main() {
  foo();
}

extern "C" {
  void foo() {
    std::cout << inst.v << std::endl;
  }
}

但是我非常惊讶地发现,使用g 4.6.1和4.4.4我必须明确地写::在朋友void :: foo()中;否则友谊不行.这个::只有当它是extern“C”时才需要.

这是编译器bug /问题吗?我没想到这个行为.
>如果它不是一个bug,为什么这是必需的,但只有当它是extern“C”而不是没有它?名称查找规则的更改如何,这使得这是必要的?

我被困了这可能有一些规则,我找不到.

解决方法

[n3290: 7.3.1.2/3]: Every name first declared in a namespace is a
member of that namespace. If a friend declaration in a non-local class
first declares a class or function the friend class or function is a
member of the innermost enclosing namespace. The name of the friend is
not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3)
95) this implies that the name of the class or function is
unqualified. until a matching declaration is provided in that
namespace scope (either before or after the class deFinition granting
friendship). If a friend function is called,its name may be found by
the name lookup that considers functions from namespaces and classes
associated with the types of the function arguments (3.4.2). If the
name in a friend declaration is neither qualified nor a template-id
and the declaration is a function or an elaborated-type-specifier,the
lookup to determine whether the entity has been prevIoUsly declared
shall not consider any scopes outside the innermost enclosing
namespace.
[..]

最内围的命名空间是匿名的,你没有限定功能名称,所以the name is not found.

命名空间need not be anonymous,也可以.

请注意,问题中的外部“C”是一个红色的鲱鱼,如the following also fails for the same reason

void foo();

namespace {
struct T {
   friend void foo();

   private: void bar() { cout << "!"; }
} t;
}

void foo() { t.bar(); }

int main() {
   foo();
}

/*
In function 'void foo()':
Line 7: error: 'void<unnamed>::T::bar()' is private
compilation terminated due to -Wfatal-errors.
*/

[alternative testcase,adapted from your original code]

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...