1
class safe_bool_base { 
protected: 
    void this_type_does_not_support_comparisons() const {} 
}; 

template <typename T=void> class safe_bool : public safe_bool_base { 
public: 
    void func() { 
    &safe_bool::this_type_does_not_support_comparisons; 
    &safe_bool_base::this_type_does_not_support_comparisons; 
    } 
}; 

template<> class safe_bool<void> : public safe_bool_base { 
public: 
    void func() { 
    &safe_bool::this_type_does_not_support_comparisons; 
    &safe_bool_base::this_type_does_not_support_comparisons; 
    } 
}; 

오류 메시지 : 보호 부재는 상기 템플릿 특수화에 방문 할 수없는 이유보호 된 멤버 액세스 에러가

zzz.cpp: In member function 'void safe_bool<void>::func()': 
zzz.cpp:7:10: error: 'void safe_bool_base::this_type_does_not_support_comparison 
s() const' is protected 
void this_type_does_not_support_comparisons() const {} 
    ^
zzz.cpp:22:24: error: within this context 
    &safe_bool_base::this_type_does_not_support_comparisons; 
        ^

이 궁금하다. 코드는 의미가 없으며 테스트 용입니다.

+1

실제로'safe_bool_base :: this_type_does_not_support_comparisons()'는 잘 작동하지만'& safe_bool_base :: this_type_does_not_support_comparisons' (함수의 주소를 취함)는 그렇지 않습니다. 그래서 문제를 파악하고 싶습니다. – immiao

답변

1

공개 클래스가 기본 클래스에서 상속되면 해당 보호 멤버는 파생 클래스 '파생 클래스의 멤버 함수에서 액세스 할 수있는 멤버 보호'파생 클래스가됩니다. 그것들은 오직 파생 클래스 자체 (그리고 그 파생 된 클래스들)를 통해서만 접근된다는 것에주의하십시오. 그러나 보호 된 멤버는 기본 클래스를 통해 액세스 할 수 없습니다. 그 이유는 &safe_bool::this_type_does_not_support_comparisons;이지만 &safe_bool_base::this_type_does_not_support_comparisons;은 작동하지 않습니다. 표준에서

, $11.4/1 Protected member access [class.protected] :

(emphasie 광산)

는 [class.access]인가 절에서 전술 한 것 이외의 추가적인 액세스 확인하면 비 정적 데이터 멤버 또는 비 정적 구성원 함수는 명명 클래스의 보호 된 구성원입니다. ([class.access.base]) 114 앞에서 설명한 것처럼 친구 또는 구성원에서 참조가 발생하기 때문에 보호 된 구성원에 대한 액세스가 허용됩니다. 일부 클래스 C. 액세스가 구성원 ([expr.unary.op])에 대한 포인터를 형성하는 경우 중첩 된 이름 지정자는 C 또는 C에서 파생 된 클래스 을 나타냅니다. 기타 모든 액세스에는 (아마도 암시적인) 이 포함됩니다 개체 표현식 ([expr.ref]).

참고 샘플 코드의 명령문 int B::* pmi_B = &B::i; // ill-formed에서 - [단부 예

class B { 
protected: 
    int i; 
    static int j; 
}; 

class D1 : public B { 
}; 

class D2 : public B { 
    friend void fr(B*,D1*,D2*); 
    void mem(B*,D1*); 
}; 

... 
void D2::mem(B* pb, D1* p1) { 
    pb->i = 1;     // ill-formed 
    p1->i = 2;     // ill-formed 
    i = 3;      // OK (access through this) 
    B::i = 4;      // OK (access through this, qualification ignored) 
    int B::* pmi_B = &B::i;  // ill-formed 
    int B::* pmi_B2 = &D2::i;  // OK 
    j = 5;      // OK (because j refers to static member) 
    B::j = 6;      // OK (because B::j refers to static member) 
} 

... 

예]이 경우, 오브젝트 식의 클래스 C 또는 C로부터 파생 된 클래스이어야한다 표준, 기본적으로 코드의 경우와 같습니다. BTW 템플릿 특수화와 관련이 없습니다.

+0

글쎄, 컴파일러는 템플릿 선언에서 전문을 출력하지 않는다고보고합니다. 그것은 템플릿 전문화에 대해 생각하게 만들었다. 자세한 설명 주셔서 감사합니다! – immiao

관련 문제