2012-06-07 35 views
9

Im tratando de definir una función amiga de clase fuera del espacio de nombres de la siguiente manera:amigo clase función dentro de un espacio de nombres

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

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

Im que consigue un error decir que existe ambigüedad. y hay dos candidatos void A::f(A::window); y void f(A::window). Entonces mi pregunta es:

1) Cómo hacer que la función global void f(A::window rhs) sea una amiga de la clase A :: ventana.

EDIT: (Después de leer las respuestas)

2) ¿por qué necesito para calificar la función miembro f dentro de la clase de ventana que ser global haciendo ::f(window)?

3) ¿Por qué necesito predefinir la función f (A :: ventana) en este caso particular, mientras que cuando la clase no está definida dentro de un espacio de nombres es okey para la función declarada después de que se declare la función un amigo.

Respuesta

15

Además de añadir un :: necesita que transmita a conocer, por ejemplo .:

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; 
} 

Tenga en cuenta que para esta declaración adelantada funcione es necesario que transmita declarar la clase también!

+0

por lo que el :: código de acceso a espacio de nombres global es la que requiere función declarada nulo f (A :: ventana); es esto correcto. gracias por adelantado. – AlexDan

+0

Sí, esto funciona cuando la función vuelve vacía. Pero, ¿y si devuelve una instancia de una clase, digamos B? Luego, el compilador pronuncia "amigo B :: f()" porque cree que queremos decir "B :: f()" (es decir, una función de la clase B, a diferencia de una función global). Alguna solucion a eso? –

+0

No veo cómo puede terminar con un choque de nombres como ese legalmente, ¿puede mostrarlo en algo como ideone? – Flexo

4

Esto debe hacerlo: hay que declara hacia adelante para dejar en claro f está en el espacio de nombres global (y no presentar estática):

#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() 
{ 
} 
Cuestiones relacionadas