2012-06-12 2 views
2

Rect에서 Rect로 또는 그 반대로 변환을 허용하는 변환 생성자가있는 템플릿 기반 클래스 Rect가 있습니다. 그러나 코드를 컴파일 할 때 컴파일러는 생성자가 클래스의 보호 된 멤버에 액세스 할 수 없다는 오류를 제공합니다. 여기 코드입니다 :템플릿 변환 생성자가 보호 된 데이터 멤버에 액세스하지 못함

#include <iostream> 
#include <list> 
#include <algorithm> 

using namespace std; 

template< typename T > 
class Rect{ 
protected: 
    T width, height; 
public: 
    Rect(T a, T b){ 
    width = a; 
    height = b; 
    } 
    template< typename U > 
    Rect(Rect<U> const &r){ 
    width = r.width; 
    height = r.height; 
    } 
    int area(){ 
    return width*height; 
    } 
}; 

int main(){ 
    Rect<int> a(3,4); 
    Rect<float> b(a); 
    cout<<b.area()<<endl; 
} 

을 그리고 여기에 컴파일 오류입니다 :

test.cpp: In constructor ‘Rect<T>::Rect(const Rect<U>&) [with U = int, T = float]’: 
test.cpp:28:18: instantiated from here 
test.cpp:10:7: error: ‘int Rect<int>::width’ is protected 
test.cpp:18:5: error: within this context 
test.cpp:10:14: error: ‘int Rect<int>::height’ is protected 
test.cpp:19:5: error: within this context 

내가 템플릿 특수화를 사용하여 친구 클래스를하지 않고이 문제를 해결하려면. 내가 아는 한 당신은 생성자를 친구로 선언 할 수 없습니다. 어떤 아이디어?

편집 : 의미에 대한 수정을했습니다. 그래서 내가 생성하려고하는 생성자는 실제로 변환 생성자입니다.

편집 2 : 프로그램을 수정했습니다. 당신이 알아야 할

+0

@chris 아니요 작동하지 않습니다. – gibraltar

+0

참조하십시오 : http://stackoverflow.com/questions/1599171/c-class-member-access-problem-with-templates/ – kennytm

+1

왜'width'와'height'는 type 대신'int' 유형으로 선언됩니다 'T'? – cdhowie

답변

3

언급 한 K-ballo와 마찬가지로 Rect<int>Rect<float>은 서로 다른 유형이며 서로의 비공개 및 보호 된 멤버에 액세스 할 수 없습니다. 당신은 명시 적으로 클래스 (like so)에 다음 템플릿 친구 선언을 추가하여이를 허용 할 수 있습니다 :

template <typename U> friend class Rect; 

는 의미 적, 이것이 의미하는 "모든 종류의 U를 들어, 내 개인 보호 회원 클래스 Rect<U> 액세스 권한을 부여"- 모든 Rect 인스턴스화에서 모든 다른 Rect 인스턴스화로 나가는 허가 권한 부여입니다.

widthheight에 대한 접근자를 추가하는 경우 (K-ballo에서 제안하는대로)이 작업이 필요하지 않습니다. 그러면 변환 생성자에서 해당 접근자를 사용하고 완전히 친구 정의를 사용할 수 있습니다. 나는 그의 해결책을 더 좋아할 것이다. 나는 가능한 한 다른 선택 방안으로 나의 것을 제공하고 익숙하지 않은 개념 (친구, 특히 템플릿 친구)을 소개합니다.

4

우선은 템플릿 생성자복사 생성자 적이 없다는 것입니다. 둘째로 Rect<T>Rect<U>인데 std::stringstd::vector과 관련이 없으므로 T != U은 다른 관련없는 클래스입니다.

당신은 widthheight에 액세스 할 수있는 방법을 제공해야하고 변환 생성자 새로운 Rect를 만드는 등의 액세스 방법을 사용합니다.

+0

@cdhowie 컴파일 중에 부분 특수화 오류가 발생합니다. 어쩌면 우리에게 더 나은 작업 코드를 제공 할 수 있다면 어떨까요? 어쩌면 나는 뭔가를 놓치고있다. – gibraltar

+0

@gibraltar : _friend templates_은 복잡한 짐승입니다. 'Rect'는 자신의 _width_와 _height_를 알 수있는 방법을 제공 할 필요가 없습니까? –

관련 문제