템플릿

윤이령·2026년 4월 22일

함수 템플릿

  • 데이터 형식 추론하는데 시간이 많이 소요됨.
  • 형식이 모호하면 추론이 불가능
#include <iostream>
#include <string>

using namespace std;

template <typename T>
T data_sum(T operand1, T operand2) {
	return operand1 + operand2;
}

int main() {
	int data1 = 2, data2 = 5;
	double data3 = 4.5, data4 = 8.9;
	string data5 = "Hello", data6 = "World";

	cout << data_sum(data1, data2) << endl;
	cout << data_sum(data3, data4) << endl;
	cout << data_sum(data5, data6) << endl;

	return 0;
}
  • 호출문에서 인자를 입력하기 저에 <> 로 데이터형식 명시
#include <iostream>
#include <string>

using namespace std;

template <typename T>
T data_sum(T operand1, T operand2) {
	return operand1 + operand2;
}

int main() {
	string data5 = "Hello", data6 = "World";
	cout << data_sum<string>(data5, data6) << endl;

	return 0;
}

템플릿 특수화

  • 특수한 상황일 때만 별도의 함수 템플릿으로 만들어 처리하는 방법
  • 특별한 데이터 형식만 별도로 처리할 때 사용
  • 특정 데이터마 ㄴ다르게 처리해야 할 때는 템플릿 특수화를 이용하는 것이 좋음
#include <iostream>
#include <string>

using namespace std;

template <typename T>
T data_sum(T operand1, T operand2) {
	return operand1 + operand2;
}

template<>
double data_sum(double operand1, double operand2) {
	return (int)operand1 + (int)operand2;
}

int main() {
	int data1 = 2, data2 = 5;
	double data3 = 4.5, data4 = 8.9;
	string data5 = "Hello", data6 = "World";

	cout << data_sum(data1, data2) << endl;
	cout << data_sum(data3, data4) << endl;
	cout << data_sum(data5, data6) << endl;

	return 0;
}

클래스 템플릿

  • 데이터 형식까지 범용으로 사용할 수 있음
#include <iostream>
using namespace std;

template <typename Type1, typename Type2>
class data_package {
public:
	data_package(Type1 first, Type2 second) : first(first), second(second) {}
	void print_out_element() {
		cout << "첫번째 요소" << first << ", 두번째 요소" << second << endl;
	}
private:
	Type1 first;
	Type2 second;
};

int main() {
	data_package<int, double> template_inst1(5, 10.5);
	data_package<string, int> template_inst2("문자열", 10);

	template_inst1.print_out_element();
	template_inst2.print_out_element();

	return 0;
}

부분 특수화

#include <iostream>
using namespace std;

template <typename Type1, typename Type2>
class data_package {
public:
	data_package(Type1 first, Type2 second) : first(first), second(second) {}
	void print_out_element() {
		cout << "첫번째 요소" << first << ", 두번째 요소" << second << endl;
	}
private:
	Type1 first;
	Type2 second;
};

//부분 특수화
template <typename T>
class data_package<string, T> {
public:
	data_package(string first, T second) : first(first), second(second) {};
	void print_out_element() {
		cout << first << "과 함께 입력된, 두번째 요소 : " << second << endl;
	}
private:
	string first;
	T second;
};

int main() {
	data_package<int, double> template_inst1(5, 10.5);
	data_package<string, int> template_inst2("문자열", 10);

	template_inst1.print_out_element();
	template_inst2.print_out_element();

	return 0;
}

중첩 클래스 템플릿

  • 안쪽 클래스를 멤버변수처럼 사용
  • 안쪽 클래스를 독립된 객체로 선언해서 사용
#include <iostream>

using namespace std;

template <typename Type1, typename Type2>
class data_package {
public:
  template <typename Type3>            // 바깥쪽 템플릿 매개변수 사용 
  class nested_class_data_package {    // 안쪽 클래스
  public:
    nested_class_data_package(Type3 data) : nested_class_data(data) {}
    Type3 get_element() { return nested_class_data; }
    Type3 nested_class_data;
  };

  template <typename Type4>    // 새 템플릿 매개변수 사용
  class nested_class {         // 안쪽 클래스
  public:
    nested_class(Type4 data) : nested_class_data(data) {}
    void print_out_element() {
      cout << "중첩 클래스 데이터: " << nested_class_data << endl;
    }
  private:
    Type4 nested_class_data;
  };

  data_package(Type1 first, Type2 second) : first(first), second(second), internal_data(second) {}

  void print_out_element() {
    cout << "첫 번째 요소: " << first <<
      ", 두 번째 요소: " << second << endl;
    cout << "중첩 클래스 요소: " << internal_data.get_element() << endl;
  }

private:
  Type1 first;
  Type2 second;
  //안쪽 클래스를 멤버변수처럼 사용
  nested_class_data_package<Type2> internal_data;   // 멤버 변수로 선언

};
int main() {
  data_package<string, int> template_inst1("문자열", 10);
  //안쪽 클래스를 독립된 객체로 선언해서 사용
  data_package<string, int>::nested_class<int> template_inst2(500);   // 객체로 선언

  cout << "중첩 클래스 첫 번째 범례" << endl;
  template_inst1.print_out_element();

  cout << endl << "중첩 클래스 두 번째 범례" << endl;
  template_inst2.print_out_element();
}

템플릿 매개변수 기본값

  • 형식을 지정하지 않거나 전체<>로 지정하면 기본값으로 지정한 데이터 형식이 됨
#include <iostream>
using namespace std;

template <typename T = int>
class data_package {
public:
	data_package(T first) : first(first) {}
	void print_out_element() {
		cout << "템플릿 매개변수 값 : " << first << endl;
	}
private:
	T first;
};

int main() {
	data_package<> template_inst1(5);
	data_package<string> template_inst2("클래스 템플릿 기본값이 아닌 string형");
	template_inst1.print_out_element();
	template_inst2.print_out_element();

	return 0;
}

클래스 템플릿 프렌드

#include <iostream>
using namespace std;

template <typename T = int>
class data_package {
public:
	data_package(T first) : first(first) {}
	template <typename C>
	friend void printout_friend_element(C& data_object);
private:
	T first;
};

template <typename C>
void printout_friend_element(C& data_object) {
	cout << "(friend 클래스 템플릿 호출) 템플릿 매개변수 값 : " << data_object.first << endl;
}

int main() {
	data_package<> template_inst1(5);
	data_package<string> template_inst2("클래스 템플릿 기본값이 아닌 string형");

	printout_friend_element(template_inst1);
	printout_friend_element(template_inst2);
	return 0;
}

0개의 댓글