친구 템플릿
클래스 템플릿이 있을 수 있습니다 친구.클래스 또는 템플릿 클래스, 함수 또는 함수 템플릿을 템플릿 클래스에 friend가 될 수 있습니다.친구의 클래스 템플릿 또는 함수 템플릿을 특수화 있지만 않는 부분 특수화 일 수도 있습니다.
예제
다음 예제에서는 friend 함수는 함수 템플릿 클래스 템플릿 내에서 정의 됩니다.버전의 친구 함수 템플릿의 모든 인스턴스에 대 한이 코드를 생성합니다.이 구문은 클래스와 같은 템플릿 매개 변수에 따라 friend 함수에 의존 하는 경우에 유용 합니다.
// template_friend1.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <class T> class Array {
T* array;
int size;
public:
Array(int sz): size(sz) {
array = new T[size];
memset(array, 0, size * sizeof(T));
}
Array(const Array& a) {
size = a.size;
array = new T[size];
memcpy_s(array, a.array, sizeof(T));
}
T& operator[](int i) {
return *(array + i);
}
int Length() { return size; }
void print() {
for (int i = 0; i < size; i++)
cout << *(array + i) << " ";
cout << endl;
}
template<class T>
friend Array<T>* combine(Array<T>& a1, Array<T>& a2);
};
template<class T>
Array<T>* combine(Array<T>& a1, Array<T>& a2) {
Array<T>* a = new Array<T>(a1.size + a2.size);
for (int i = 0; i < a1.size; i++)
(*a)[i] = *(a1.array + i);
for (int i = 0; i < a2.size; i++)
(*a)[i + a1.size] = *(a2.array + i);
return a;
}
int main() {
Array<char> alpha1(26);
for (int i = 0 ; i < alpha1.Length() ; i++)
alpha1[i] = 'A' + i;
alpha1.print();
Array<char> alpha2(26);
for (int i = 0 ; i < alpha2.Length() ; i++)
alpha2[i] = 'a' + i;
alpha2.print();
Array<char>*alpha3 = combine(alpha1, alpha2);
alpha3->print();
delete alpha3;
}
다음 예제에서는 템플릿 특수화 된 친구는 것입니다.친구가 원래 함수 템플릿일 경우 함수 템플릿 특수화는 자동으로 친구입니다.
Friend 선언 다음 코드에 표시 하기 전에 메모를 친구로 특별 한 버전의 템플릿 선언 하는 것도 가능 합니다.이 경우의 친구 템플릿 특수화 템플릿 클래스 외부에 정의 배치 해야 합니다.
// template_friend2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <class T>
class Array;
template <class T>
void f(Array<T>& a);
template <class T> class Array
{
T* array;
int size;
public:
Array(int sz): size(sz)
{
array = new T[size];
memset(array, 0, size * sizeof(T));
}
Array(const Array& a)
{
size = a.size;
array = new T[size];
memcpy_s(array, a.array, sizeof(T));
}
T& operator[](int i)
{
return *(array + i);
}
int Length()
{
return size;
}
void print()
{
for (int i = 0; i < size; i++)
{
cout << *(array + i) << " ";
}
cout << endl;
}
// If you replace the friend declaration with the int-specific
// version, only the int specialization will be a friend.
// The code in the generic f will fail
// with C2248: 'Array<T>::size' :
// cannot access private member declared in class 'Array<T>'.
//friend void f<int>(Array<int>& a);
friend void f<>(Array<T>& a);
};
// f function template, friend of Array<T>
template <class T>
void f(Array<T>& a)
{
cout << a.size << " generic" << endl;
}
// Specialization of f for int arrays
// will be a friend because the template f is a friend.
template<> void f(Array<int>& a)
{
cout << a.size << " int" << endl;
}
int main()
{
Array<char> ac(10);
f(ac);
Array<int> a(10);
f(a);
}
다음 예제에서는 friend 클래스 템플릿 클래스 템플릿 내에서 선언 된 보여 줍니다.클래스 템플릿의 friend 클래스 템플릿 인수로 다음 사용 됩니다.Friend 클래스 템플릿 선언 된 클래스 템플릿 외부에서 정의 되어야 합니다.모든 특수화 나 부분 특수화의 friend 템플릿 원본 클래스 템플릿이의 친구 이기도합니다.
// template_friend3.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <class T>
class X
{
private:
T* data;
void InitData(int seed) { data = new T(seed); }
public:
void print() { cout << *data << endl; }
template <class U> friend class Factory;
};
template <class U>
class Factory
{
public:
U* GetNewObject(int seed)
{
U* pu = new U;
pu->InitData(seed);
return pu;
}
};
int main()
{
Factory< X<int> > XintFactory;
X<int>* x1 = XintFactory.GetNewObject(65);
X<int>* x2 = XintFactory.GetNewObject(97);
Factory< X<char> > XcharFactory;
X<char>* x3 = XcharFactory.GetNewObject(65);
X<char>* x4 = XcharFactory.GetNewObject(97);
x1->print();
x2->print();
x3->print();
x4->print();
}