дружба с функцией 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 я должен явно писать :: в friend void :: foo (); иначе дружба не сработает. Этот :: нужен только тогда, когда это extern «C» .

  1. Это ошибка / проблема компилятора? Я не ожидал такого поведения.
  2. Если это не ошибка, то почему это требуется, но только когда это extern "C" , а не без него? Что насчет изменений правил поиска имен, из-за которых это необходимо?

Я в тупике. Вероятно, для этого есть какое-то правило, которое я не могу найти.

13
задан Flexo 18 October 2011 в 15:17
поделиться