반응형

클래스 템플릿안에 friend 함수를 선언하는 방법

  • friend 함수 선언시에 함수 자체를 템플릿 모양으로 선언

  • friend 관계: N:N

#include <iostream>
using namespace std;

template<typename T>
class Point
{
    T x, y;
public:
    Point(T a = { 0 }, T b = { 0 }) : x(a), y(b) {}
    template<typename U>
    friend ostream& operator<<(ostream& os, const Point<U>& p);
};

template<typename T>
ostream& operator<<(ostream& os, const Point<T>& p)
{
    return os << p.x << ", " << p.y;
}


int main()
{
    Point<int> p(1, 2);
    cout << p << endl;

    Point<double> p2(1.2, 2.3);
    cout << p2 << endl;
}

 

  • friend 함수를 일반 함수로 구현하고 구현부를 클래스 템플릿 내부에 포함

  • friend 관계: 1:1

#include <iostream>
using namespace std;

template<typename T>
class Point
{
    T x, y;
public:
    Point(T a = { 0 }, T b = { 0 }) : x(a), y(b) {}
    friend ostream& operator<<(ostream& os, const Point<T>& p)
    {
        return os << p.x << ", " << p.y;
    }
};


int main()
{
    Point<int> p(1, 2);
    cout << p << endl;

    Point<double> p2(1.2, 2.3);
    cout << p2 << endl;
}
반응형

반응형

일반화된 복사 생성자

  • 클래스 템플릿의 멤버 함수 템플릿으로 구현하는 복사 생성자.

  • U(int) T(double)로 복사(대입) 가능하다면 Complex<U> Complex<T>에 복사(대입) 가능해야 한다.

  • friend class로 선언되어야 한다.

template<typename T> class Complex
{
    T re, im;
public:
    Complex(T a = {}, T b = {}) : re(a), im(b) {}
    T getReal() const;
    static int cnt;
    template<typename U> T func(const U& c);

    // 일반화된 복사 생성자 선언
    template<typename U>
    Complex(const Complex<U>& c);

    template<typename> friend class Complex;
};

// 일반화된 복사 생성자 구현부
template<typename T> template<typename U>
Complex<T>::Complex(const Complex<U>& c)
    : re(c.re), im(c.im)
{

}

int main()
{
    Complex<int> c1(1, 1);
    Complex<int> c2 = c1;
    Complex<double> c3 = c1;
}
반응형

반응형

템플릿과 타입의 차이

  • Complex: 템플릿 틀 자체

  • Complex<T>: 실제 타입

  • 멤버 함수안에서는 

멤버 함수안에서는 Complex<T> 대신 Complex를 사용할 수 있다.

template<typename T> class Complex
{
    T re, im;
public:
    void foo(Complex c) // 멤버 함수에서는 OK(Complex<T> 동급으로 취급)
    {

    }
};

void foo(Complex c) // 일반 함수에서는 Error
{

}

void foo(Complex c)
{
    Complex c1; // Error
    Complex<int> c2; // OK
}

 

템플릿 관련 표기법

  • 디폴트 값 표기

    • int a = 0;

    • T a = T(); // C++ 98/03

    • T a = {};  // C++11

  • 멤버 함수를 외부에 표기

  • static memeber data 외부 표기

  • 클래스 템플릿의 멤버 함수 템플릿 표기

template<typename T> class Complex
{
    T re, im;
public:
	// 디폴트 값 표기
    Complex(T a = {}, T b = {}) : re(a), im(b) {}
    T getReal() const;
    static int cnt;

    template<typename U> T func(const U& c);
};

// 클래스 템플릿의 멤버 함수 템플릿 구현
template<typename T> template<typename U>
T Complex<T>::func(const U& c)
{

}

// static 멤버 데이터 외부 구현
template<typename T>
int Complex<T>::cnt = 0;

// 멤버 함수 외부 구현
template<typename T> 
T Complex<T>::getReal() const
{
    return re;
}

int main()
{
    Complex<int> c2;
}
반응형

+ Recent posts