2014-12-10 3 views
2

이것은 정상적으로 작동하지만 뭔가 내 네임 스페이스를 사용하면 엉망입니다. 내 친구 친구 함수가 네임 스페이스가있는 보호 된 멤버에 액세스 할 수없는 이유는 무엇입니까?

이 코드를 가지고 :

.H :

class FetchRecord 
{ 
    friend KxStream& operator<<(KxStream& os, FetchRecord& r); 
protected: 
    int mId; 
}; 

통화 당 :

KxStream& operator<<(KxStream& os, FetchRecord& r) 
{ 
    os << r.mId; 
    return os; 
} 

이 잘 작동합니다. 그러나 나는 할 경우 :

.H :

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& operator<<(KxStream& os, FetchRecord& r); 
    protected: 
     int mId; 
    }; 
} 

통화 당 :

using namespace Blah; 

KxStream& operator<<(KxStream& os, FetchRecord& r) 
{ 
    os << r.mId; 
    return os; 
} 

그런 다음 친구가 자명 한 일 입니 무시 보인다 :

src/fetch.cpp:153:25: error: 'mId' is a protected member of 'Blah::FetchRecord' 

나는 무슨 일이 일어나고 있는지 아마 알 수 있습니다 - .cpp의 함수가 friend 선언의 함수와 일치하지 않습니다. 어떻게 이것을 해결합니까?

@ 업데이트 : 바로 아래에 두 가지 정답이 있습니다. 감사. 테스트를 거쳐 작동합니다. 하지만 Blah 네임 스페이스에 내 오퍼레이터 < <의 기능을 넣어야하는 것이 싫다. 기능에 대한 전체 프로토 타입이 있다면 그것은 청소기 될 것이다 : 나는 어떻게 든 앞으로 네임 스페이스 ㅋ 밖에서 그 친구의 함수를 선언 할 수 있다면,이다

KxStream& operator<<(KxStream&, Blah::FetchRecord&); 

. 그리고 나는 길을 찾았습니다 :

namespace Blah 
{ 
    class FetchRecord; 
} 

KxStream& operator<<(KxStream& os, Blah::FetchRecord& r); 

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& ::operator<<(KxStream& os, FetchRecord& r); 
    }; 
} 

당신은 펜던트 적으로 노골적인 것을 얻어야합니다. 연산자의 친구 선언에있는 "::"참고 : < <.

답변

2

두 번째 경우에 글로벌 네임 스페이스에 operator<<을 정의하면 .h 파일에서 선언 한 내용과 관련이 없습니다. 당신은 namespace Blah에 정의해야합니다

namespace Blah { 
    KxStream& operator<<(KxStream& os, FetchRecord& r) 
    { 
     os << r.mId; 
     return os; 
    } 
} 

업데이트 : 당신이 (ADL 덕분에 심지어 using namespace Blah없이 작동하기 때문에, 이상하다) 글로벌 네임 스페이스에 속하는 operator<<를 원한다면, 당신은 .H에 다음과 같이 쓸 수 있습니다 그대로 파일과 .cpp 파일을 떠나 :

namespace Blah 
{ 
    class FetchRecord; 
} 

KxStream& operator<<(KxStream& os, Blah::FetchRecord& r); 

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& ::operator<<(KxStream& os, FetchRecord& r); 
     //    ^^^^ 
    protected: 
     int mId; 
    }; 
} 
+0

수정하고 작동합니다. 그러나 나는 다른 방법이 있었으면 좋겠다. 내 operator << 함수가 Blah 네임 스페이스에 있어야하는 것은 싫다. –

+0

@RafaelBaptista 왜 당신은 그것을 좋아하지 않아? –

+0

Lol. 정확하게 방금 내 질문에 대한 업데이트에 게시 한 내용입니다. –

1

using namespace Blah에도 불구하고, 여전히 Blah가 선언 된 네임 스페이스 이었기 때문에 함수를 정의 할 때 이름을 규정 할 필요가있다. 그것은이어야합니다 :

KxStream& Blah::operator<<(KxStream& os, FetchRecord& r) 
+0

정확하고 올바르게 작동합니다. 그러나 나는 다른 방법이 있었으면 좋겠다. 내 operator << 함수가 Blah 네임 스페이스에 있어야하는 것은 싫다. –

+1

@RafaelBaptista 그런 다음 친구로 선언하기 전에 네임 스페이스 외부에서 선언하십시오. – 0x499602D2

+0

아주 못생긴 방법을 찾을 수 없습니다. 예 : 일반 forward는 선언하고 gcc는 두 개의 다른 함수로 취급합니다. –

관련 문제