#include <iostream>
using namespace std;
class Point
{
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
};
int main()
{
Point p1(1, 2);
cout << p1 << endl; // 요걸 쓰고 싶다
}
#include <iostream>
using namespace std;
class Point
{
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
friend ostream& operator<<(ostream& os, const Point& p);
};
ostream& operator<<(ostream& os, const Point& p)
{
return os << p.x << ", " << p.y;
}
만약 Point가 template이라면??
#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);
};
template<typename T>
ostream& operator<<(ostream& os, const Point<T>& p)
{
return os << p.x << ", " << p.y;
}
int main()
{
Point<int> p1(1, 2);
cout << p1 << endl; // error! ???
}
왜 에러가 나지?
#include <iostream>
using namespace std;
template<typename T> void foo(T a)
{
cout << "T" << endl;
}
void foo(int a)
{
cout << "int" << endl;
}
int main()
{
foo(3); // 'int' 출력 됨 -> 정확한 타입이 우선된다.
}
#include <iostream>
using namespace std;
template<typename T> void foo(T a)
{
cout << "T" << endl;
}
void foo(int a); // 구현부를 지워 둠.
int main()
{
foo(3); // error - 정확한 선언의 구현부가 없기에 링크에러 발생
}
#include <iostream>
using namespace std;
template<typename T> class Point{};
template<typename T> void foo(Point<T> a)
{
cout << "T" << endl;
}
void foo(Point<int> a) { cout << "int" << endl; }
int main()
{
Point<int> p;
foo(3); // int - 역시 정확한 버전을 사용함.
}
다시 문제로 돌아가 보자.
#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);
};
// 함수 템플릿
template<typename T>
ostream& operator<<(ostream& os, const Point<T>& p)
{
return os << p.x << ", " << p.y;
}
int main()
{
Point<int> p1(1, 2); // 여기가 호출 되는 순간 Point<int>를 생성하게 된다.
cout << p1 << endl; // error! ???
}
// T : int이기에
class Point<int>
{
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {}
friend ostream& operator<<(ostream& os, const Point<int>& p);
// 이렇게 된 순간 operator<<는 Point<int>로 확정이 되어 버린다.
// friend ostream& operator<<(ostream& os, const Point<int>& p);
// 를 찾을수 없기에 에러가 발생하는 것.
};
해결법?
#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);
// 함수 템플릿을 friend로 선언함으로 해결가능.
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> p1(1, 2); // 여기가 호출 되는 순간 Point<int>를 생성하게 된다.
cout << p1 << endl;
}
하지만 더 좋은 방법이 있다.
#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);
// 구현을 클래스 내부에 한다.
friend ostream& operator<<(ostream& os, const Point<T>& p)
{
return os << p.x << ", " << p.y;
}
};
// 함수 템플릿
template<typename T>
ostream& operator<<(ostream& os, const Point<T>& p)
int main()
{
Point<int> p1(1, 2); // 여기가 호출 되는 순간 Point<int>를 생성하게 된다.
cout << p1 << endl;
}