2012-06-07 3 views
9

Im пытается определить функцию друга класса вне пространства имен, как это:друг класса функция внутри пространства имен

namespace A{ 
class window{ 
    private: 
    int a; 
    friend void f(window); 
}; 
} 

void f(A::window rhs){ 
cout << rhs.a << endl; 
} 

Im получает сообщение об ошибке говорит, что существует неоднозначность. и есть два кандидата void A::f(A::window); и void f(A::window). Поэтому мой вопрос:

1) Как сделать глобальную функцию void f(A::window rhs) другом класса A :: window.

EDIT: (После прочтения ответов)

2) почему мне нужно квалифицировать функции члена е внутри оконного класса должен быть глобальным, делая ::f(window)?

3) почему в этом конкретном случае мне нужно предусмотреть функцию f (A :: window), тогда как когда класс не определен внутри пространства имен, это означает, что функция объявляется после того, как функция объявлена друг.

ответ

15

Как добавить :: вам необходимо переслать объявить, например .:

namespace A { class window; } 

void f(A::window); 

namespace A{ 
    class window{ 
    private: 
    int a; 
    friend void ::f(window); 
    }; 
} 

void f(A::window rhs){ 
    std::cout << rhs.a << std::endl; 
} 

Обратите внимание, что для этого прямого заявления на работу вам необходимо переслать объявить класс тоже!

+0

так :: префикс для доступа к глобальному пространству имен является тот, который требуется предварительно объявленная функция void f (A :: window); это верно. заранее спасибо. – AlexDan

+0

Да, это работает, когда функция возвращает void. Но что, если он возвращает экземпляр класса, скажем B? Затем компилятор barfs на «friend B :: f()», потому что он думает, что мы имеем в виду «B :: f()» (т. Е. Функцию класса B, в отличие от глобальной функции). Любое решение? –

+0

Я не понимаю, как вы можете столкнуться с таким именем, как это легально, - можете ли вы показать его на чем-то вроде идеона? – Flexo

4

Это следует сделать это: вам нужно вперед декларирует, чтобы понять, е в глобальном пространстве имен (а не файл статика):

#include <string> 
#include <iostream> 

using namespace std; 

////// forward declare magic: 

namespace A{ class window; }  
void f(A::window rhs); 

////// 

namespace A { 
    class window { 
     private: 
      int a; 
      friend void ::f(window); 
    }; 
} 

void f(A::window rhs) { 
    cout << rhs.a << endl; 
} 

int main() 
{ 
} 
Смежные вопросы