2012-03-19 2 views
2
class Foo 
{ 
    template <typename T> friend void T::persist(void); 
    int test; 
}; 

class Bar 
{ 
    Foo foo; 
    void persist(void) { foo.test = 42; } // fails 
} 

이렇게하면, 그것을 정의하는 모든 클래스의 persist() 멤버 메소드가 foo의 친구가되기를 바랍니다. 이상한 친구가 생겨나지만 아무것도하지 않는 것처럼 보입니다.아주 간단한 템플릿 친구 선언

미리 감사드립니다.

+3

내가 아는 한, 당신은 무료 함수, 클래스 및 템플릿 만 친해질 수 있습니다. 한 클래스에서 하나의 멤버 함수 만 친구가 될 수는 없습니다. –

+0

@KerrekSB 클래스가 지정되지 않은 경우에는 사용할 수 없습니다. 템플릿으로는 작동하지 않습니다. – hvd

+0

@hvd : 알겠습니다, 감사합니다! –

답변

1

당신은 그렇게 할 수 없습니다. 모두 유형의 구성원이 될 수 없으며 템플릿 친구 인 선언이 잘못되었습니다. 친구 선언 템플릿 아니라고

class Foo 
{ 
    template <typename T> 
    friend void T::persist(void); 

    int test; 
}; 

참고 :에는 템플릿가 없습니다. 템플릿 함수 또는 클래스와 친구가 될 수 있지만 위의 코드에는 해당 템플릿이 없습니다.

간단한 해결 방법은 파생 접근 제공되는 헬퍼 클래스를 생성하는 것입니다 :

class Foo { 
    friend class FooAccessor; 
    int value; 
}; 
class FooAccessor { 
protected: 
    void write(Foo& f, int value) { 
    f.value = value; 
    } 
}; 
class FooUser : private FooAccessor { 
    Foo f; 
    void persist() { 
     write(f, 42); 
    } 
}; 

을하지만 당신은주의, 디자인을 다시 방문하고 대안을보고 할 수 있습니다 그 제조 분야 private 다음 다른 모든 클래스가 friend 선언을 통해 액세스 할 수있게하는 것은 필드를 공개하는 것보다 훨씬 낫지 않습니다. 성취하려는 것을 설명하는 데 관심이 있다면 누군가가 당신을 도울 수 있습니다.