2012-01-23 27 views
50

Hãy nói rằng tôi là tạo ra một lớp học cho một cây nhị phân, BT, và tôi có một lớp học trong đó mô tả một yếu tố của cây, BE, một cái gì đó giống nhưMẫu lớp với bạn bè lớp mẫu, những gì đang thực sự xảy ra ở đây?

template<class T> class BE { 
    T *data; 
    BE *l, *r; 
public: 
... 
    template<class U> friend class BT; 
}; 

template<class T> class BT { 
    BE<T> *root; 
public: 
... 
private: 
... 
}; 

Điều này dường như làm việc; tuy nhiên tôi có câu hỏi về những gì đang xảy ra bên dưới.

tôi ban đầu đã cố gắng để tuyên bố những người bạn như

template<class T> friend class BT; 

tuy nhiên nó xuất hiện cần thiết để sử dụng U (hoặc một cái gì đó khác hơn T) ở đây, tại sao điều này? Có phải ngụ ý rằng bất kỳ BT cụ thể nào là bạn của bất kỳ lớp học cụ thể BE nào không?

Trang IBM trên mẫu và bạn bè có ví dụ về các loại quan hệ bạn bè khác nhau cho các chức năng chứ không phải các lớp (và đoán một cú pháp chưa hội tụ trên giải pháp). Tôi muốn hiểu làm thế nào để có được các thông số kỹ thuật chính xác cho các loại mối quan hệ bạn bè tôi muốn xác định.

Trả lời

76
template<class T> class BE{ 
    template<class T> friend class BT; 
}; 

Không được phép vì thông số mẫu không được tô bóng lẫn nhau. Mẫu lồng nhau phải có tên thông số mẫu khác nhau.


template<typename T> 
struct foo { 
    template<typename U> 
    friend class bar; 
}; 

Điều này có nghĩa rằng bar là một người bạn của foo không phân biệt đối số mẫu bar 's. bar<char>, bar<int>, bar<float> và bất kỳ số nào khác bar sẽ là bạn của foo<char>.


template<typename T> 
struct foo { 
    friend class bar<T>; 
}; 

Điều này có nghĩa rằng bar là một người bạn của foo khi bar 'mẫu đối số của trận đấu foo' s. Chỉ bar<char> sẽ là bạn của foo<char>.


Trong trường hợp của bạn, friend class bar<T>; phải đủ.

+2

xây dựng này trong mã bạn lớp tôi BT ném một lỗi cho dòng người bạn lỗi : 'BT' không phải là mẫu ngay cả khi được khai báo sau là mẫu lớp BT { ... } –

+1

Vì vậy, bí mật là tôi cần phải chuyển tiếp khai báo BT để sử dụng lớp bạn bè BT ; dòng trong BE, nhưng không cho mẫu lớp người bạn BT ;. Cảm ơn đã giúp đỡ! –

+16

Để cụ thể hơn: bạn phải chuyển tiếp khai báo 'mẫu lớp BT;' _before_ định nghĩa BE, và sau đó sử dụng 'lớp người bạn BT ;' _inside_ lớp BE. –

-1

Trong trường hợp của tôi giải pháp này hoạt động chính xác:

template <typename T> 
class DerivedClass1 : public BaseClass1 { 
    template<class T> friend class DerivedClass2; 
private: 
int a; 
}; 

template <typename T> 
class DerivedClass2 : public BaseClass1 { 
    void method() { this->i;} 
}; 

Tôi hy vọng nó sẽ rất hữu ích.

+5

Giải pháp đó hoạt động chính xác như thế nào khi bạn đang che giấu các tham số mẫu và nếu không, không cho phép bạn bè của DerivedClass2 truy cập vào DerivedClass1 để sử dụng? – kornman00

1

để làm bạn với nhau cùng một kiểu struct:

template<typename T> 
struct Foo 
{ 
    template<typename> friend struct Foo; 
}; 

lưu ý rằng trong template<typename> friend struct Foo; bạn không nên viết T sau typename/class; nếu không nó sẽ gây ra lỗi template parm shadowing.

+3

Vui lòng cải thiện câu trả lời của bạn. – swiftBoy

1

Nó không cần thiết phải đặt tên cho các thông số để bạn có được điểm ít thất bại nếu refactoring:

 template <typename _KeyT, typename _ValueT> class hash_map_iterator{ 
     template <typename, typename, int> friend class hash_map; 
     ... 
Các vấn đề liên quan