#include <iostream>
using namespace std;
template <typename T>
T reverse (T x)
{
return (-x);
}
int main() {
int a = 10;
float b = 15.4;
cout<<reverse(a)<<endl;
cout<<reverse(b)<<endl;
return (0);
}
위 코드는 템플릿을 사용하는 예시이다
main 코드에 있는 reverse(a) 에서 a는 int 로 분류가 된다 왜냐하면 int a = 10; 이라고 값을 지정 했기 때문이다.
reverse(b)는 float 이다
template<typename T>
T findLargest( T x, T y, T z ) {
T largest;
largest = (x < y)? y : x;
largest = (largest < z)? z: largest;
return largest;
}
largest = (x < y) ? y : x; 이 부분을 설명하기 위해서 조건을 이해 해야한다.
( E1 ) ? E2 : E3;
if E1의 조건을 만족하면 E2 값을 내보내고 그렇지 않다면 E3 값을 내보낸다
에를 들어 x 는 5 y 는 10 z 는 15 라고 가정해보자
largest = (5 < 10) ? 먼저 살펴보면 5 는 10 보다 작다 그러니 true 값을 내보낸다 조건이 true 이므로
largest 는 y :x ( 10 : 5 ) 즉 10 을 값으로 내보낸다
그 다음 largest를 살펴보면 (10 < z ) ? z : 10 이 되는데 (10 < 15 ) 이므로 true 이다
그러므로 z 인 15 를 largest 로 내보낸다.
int main() {
int a = 5, b = 10, c = 3;
int largestInt = findLargest(a, b, c);
double d = 2.3, e = 3.6, f = 1.2;
double largestDouble = findLargest(d, e, f);
// Outputs: 10 and 3.6
std::cout << "Largest int: " << largestInt << std::endl;
std::cout << "Largest double: " << largestDouble << std::endl;
return 0;
}
이런식으로 main 코드를 짜고 template 을 설정 해주면 findLargest 만 불러와서 3 개의 수의 최대값을 쉽게 나타낼 수 있다
operator 에 관하여
#include <iostream>
using namespace std;
class PhoneCall {
friend ostream& operator<<(ostream&, const PhoneCall&); // Declare friend function
private:
int minutes; // Private data member
public:
PhoneCall(int m = 0) : minutes(m) {} // Constructor with default value
// Overloading < operator for comparison, but not relevant to operator<< explanation
bool operator<(const PhoneCall& p) {
return minutes < p.minutes;
}
};
// Definition of the overloaded << operator
ostream& operator<<(ostream& out, const PhoneCall& p) {
out << "Phone call lasted " << p.minutes << " minutes";
return out; // Return ostream to allow chaining
}
int main() {
PhoneCall call(10);
// Using the overloaded << operator to print the PhoneCall object
cout << call << endl; // Outputs: Phone call lasted 10 minutes
return 0;
}
operator 는 주로
(반환형 return_type) operator(연산자 symbol) (연산을 할 대상 parameters)
반환형 return_type 은 오퍼레이터가 불러와야하는 값
operator 는 연산자의 타입에 따라 오버로딩
연산을 할 대상 parameters 는 오퍼레이터가 연산을 해야하는 대상이다
그렇다면 위 코드를 참조하면
bool (반환형) operator < (연산자 symbol) (const PhoneCall& p) (연산을 할 대상 parameters) 가 된다
(const PhoneCall& p) 는 (const ClassName& other) 형식이라고 생각하면 된다
template<typename T>
void repeatValue( T val, int num ) {
for( int i=0; i<num; i++ )
cout << val << " ";
cout << endl;
}
T val 을 참고해서 val을 코드 내에서 찾는다
템플릿 안에 있는 모든 데이터 타입에 오퍼레이터인 << 가 부여되어야 한다
class Store {
friend ostream& operator<<(ostream&, const Store&);
private:
int id;
string address;
string manager;
public:
Store(int =0, string ="", string ="");
};
Store::Store(int n, string addr, string m) {
id = n;
address = addr;
manager = m;
}
ostream& operator<<(ostream &out, const Store &s) {
out << "Number: " << s.id << endl;
out << "Address: " << s.address << endl;
out << "Manager: " << s.manager << endl;
return out;
}
출력 오퍼레이터 Stream operators ('<<' , '>>') 예시
friend std::ostream& operator<<(std::ostream& out, const ClassName& obj); // Example: Stream insertion
insertion opreator 를 오버로드 했다 ostream& 은 왼쪽이되고 const store&는 오른쪽이된다.
private 은 attribute들 이고
public 은 기본 constructor 이다
constructor 인 public 안에 있는 store의 값을 부여하는 코드인 implementation 코드가 있다
overloaded 된 instertion operator 인 ostream & operator<< 이다
opertor<< 는 friend 로 overloaded 되어야 한다.
friend 는 private에 엑세스 할수있기 때문에
s.id s.address 그리고 s.manager가 가능해진다
template<typename T>
void repeatValue( T val, int num ) {
for( int i=0; i<num; i++ )
cout << val << " ";
cout << endl;
}
int main() {
int a = 12;
float b = 12.5;
double c = 23.882;
Store s(1, "1 Northfield Ave", "Alice");
repeatValue( a, 3 );
repeatValue( b, 5 );
repeatValue( c, 7 );
repeatValue( s, 2 );
}
a 는 템플릿을 참고해서 T val 이기 때문에 a 는 val이 된다
하지만 main 코드에서 int a = 12 라고 값을 지정했으므로
a 는 3 과 같이 int 가 된다.
b는 float
c는 double
마지막 s 는 Store 이다.
2개의 템플릿을 사용하는 경우
template< typename T, typename U >
void displayAndCompare(T val1, U val2) {
cout << "val1=" << val1 << ", val2=" << val2 << endl;
if(val1 < val2)
cout << "The second one is larger." << endl;
else if(val1 == val2)
cout << "They are the same." << endl;
else
cout << "The first one is larger." << endl;
}
3 개의 오퍼레이터가 있다
<< , < , ==
class PhoneCall {
friend ostream& operator<<(ostream&, const PhoneCall&);
private:
int minutes;
public:
PhoneCall(int = 0);
bool operator<( const PhoneCall & ); // PhoneCall < PhoneCall
bool operator<( int n ); // PhoneCall < int
bool operator==( const PhoneCall & ); // PhoneCall == PhoneCall
bool operator==( int n ); // PhoneCall == int
};
위 코드에는 operator 가 5개 있다
제일 처음 friend ostream& operator<<(ostream&, const PhoneCall&); 에서의 "operator<<"
bool operator<( const PhoneCall & ); 에서의 "operator<"
bool operator<( inst n ); 같은 operator< 이지만 각각 다른 type 이기 때문에 다른 operator 로 분류된다
bool operator==( const PhoneCall & ); 에서의 "operator=="
bool operator==( int n ); 같은 operator== 이지만 다른 type
ostream& operator<<( ostream& ost, const PhoneCall& p ) {
ost << p.minutes;
return ost;
}
PhoneCall::PhoneCall(int value) : minutes(value){}
bool PhoneCall::operator<( const PhoneCall& p ) {
return ( (minutes < p.minutes)? true: false ); }
bool PhoneCall::operator<( int m ) {
return ( (minutes < m)? true: false ); }
bool PhoneCall::operator==( const PhoneCall& p ) {
return ( (minutes == p.minutes) ? true: false ); }
bool PhoneCall::operator==( int m ) {
return ( (minutes == m)? true: false ); }
member function 은 classname :: operator 이 붙는 코드들이다
ostream& operator<< 코드는
PhoneCall& p 를 참조해서 private attirbute 인 p.minutes 으로 보내고 ost를 이용해 결과값으로 내보낸다
mintues 의 값이 불러오는 값인 int, const들 보다 큰지에 대해 비교하는 템플릿들이다
int main() {
double a = 3.8, b=4.5, c=6.825;
float x = 3.1415;
displayAndCompare( a, b );
displayAndCompare( a, x );
PhoneCall call1( 5 );
PhoneCall call2( 8 );
displayAndCompare( call1, call2 );
displayAndCompare( call1, 5 );
}
displayAndCompare( a, b );
- T 는 double
- U 는 double
- double a = 3.8, b=4.5, c=6.825; 이여서 a 와 b 가 double 이여서 T 와 U 도 double 이다
displayAndCompare( a, x );
- T 는 double
- U 는 float
- float x = 3.1415; 이기 때문에 x 만 float
displayAndCompare( call1, call2 );
- T 는 PhoneCall
- U 는 PhoneCall
- PhoneCall call1( 5 );
- PhoneCall call2( 8 ); 이기 때문에 둘 다 PhoneCall임
displayAndCompare( call1, 5 );
- T 는 PhoneCall
- U 는 int
오버로딩을 하는 템플릿의 타입을 정하고 싶다면
someFunction<char>(someArgument);
usigned 템플릿 typename T 가 없는 템플릿
template<unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
return strcmp(p1, p2);
}
compare("hi", "mum"); produces
int compare(const char (&p1)[3], const char (&p2)[4])
compare ("hi", "mum"); 코드를 살펴보면 p1 은 hi 가 되고 p2 는 mum 이 된다
hi 는 p1이 되고 [N] 은 3을 나타낸다
mum 은 p2가 되고 [M] 은 4를 나타낸다
0 1 2 0 1 2 3
h i \n m u m \n 이런식으로 사이즈는 3 과 4 가 된다
템플릿 매개변수가 2개 이상일때
template<typename T1, typename T2>
class ClassName {
private:
T1 attribute1; // 첫 번째 템플릿 매개변수를 사용한 데이터 타입의 속성
T2 attribute2; // 두 번째 템플릿 매개변수를 사용한 데이터 타입의 속성
public:
// 생성자: 두 개의 인자를 받아서 속성 초기화
ClassName(const T1& a, const T2& b) : attribute1(a), attribute2(b) {}
// 첫 번째 속성을 반환하는 멤버 함수
T1 getAttribute1() const {
return attribute1;
}
// 두 번째 속성을 반환하는 멤버 함수
T2 getAttribute2() const {
return attribute2;
}
};
위 코드와 같이 typename 을 2 개 작성한다.
private 에는 각 typename 의 데이터가 어떠한 데이터를 의미하는지 지정해주면 된다.
const 를 붙이는 이유는 수정할 수 없는 값이라는 의미로 사용된다.
'코딩 > C++' 카테고리의 다른 글
[C++] Struct, Union 이해하기 (0) | 2025.01.21 |
---|---|
[c++] using namespace 사용하기 (0) | 2024.08.19 |
[C++] .txt 등 파일 열기, 랜덤 값 생성 코드 (0) | 2024.07.17 |
[Linux] Ubuntu Compile 컴파일 하는 법 + 파일 실행 법 (0) | 2024.07.10 |
C++ 입문 (0) | 2024.07.03 |