#include <iostream>
#include <sstream>
#include <string>
template <typename T1, typename T2>
std::string combine(const T1& a, const T2& b) {
std::stringstream ss;
ss << a << b;
return ss.str();
}
int main() {
std::cout << combine("Age: ", 23) << "\n"; // Age: 23
std::cout << combine(std::string("X="), 3.14) << "\n"; // X=3.14
}
template<typename T1> 함수에서 매개변수를 const T1& a처럼 const 참조로 받는 이유는 다음 3가지입니다.
T1 a = ...; // 값 전달 (복사 발생)
const T1& a = ...; // 참조 전달 (복사 없음)
T1이 int, double 같이 작은 타입이면 복사해도 부담이 없지만,std::string, std::vector, 사용자 정의 클래스 등 큰 객체면 복사 비용이 큽니다.📌 참조로 넘기면 복사 없이 원본을 그대로 사용하므로 성능이 좋아집니다.
template <typename T>
void print(const T& a) {
std::cout << a;
}
const를 붙이면 a를 함수 안에서 수정할 수 없게 됩니다.print(std::string("Hello"));
std::string("Hello")는 임시 객체입니다.const T&는 임시 객체도 받을 수 있습니다.| 표현 | 복사 발생 | 수정 가능 | 임시 객체 전달 가능 |
|---|---|---|---|
T a | ✅ 있음 | ✅ 가능 | ✅ 가능 |
T& a | ❌ 없음 | ✅ 가능 | ❌ 안 됨 |
const T& a | ❌ 없음 | ❌ 불가 | ✅ 가능 |
const T&는 복사 없이, 읽기 전용으로, 임시 객체까지 받을 수 있어서 C++에서 가장 안전하고 효율적인 방식입니다.
const T atemplate <typename T>
void print(const T a) {
std::cout << a;
}
즉, const T a는 T a와 똑같이 복사해서 함수로 넘기는데, 그 안에서 수정 못 하게만 막은 것이에요.
const T& atemplate <typename T>
void print(const T& a) {
std::cout << a;
}
| 항목 | const T a | const T& a |
|---|---|---|
| 복사 발생 | ✅ yes | ❌ no (참조) |
| 수정 가능 여부 | ❌ no | ❌ no |
| 임시 객체 전달 | ✅ 가능 | ✅ 가능 |
| 속도와 효율성 | 느릴 수 있음 (복사) | 빠름 (참조) |
int, double, char) 이면 const T 써도 괜찮음 (복사 비용이 거의 없음)string, vector, 사용자 정의 클래스) 이면 반드시 const T& 쓰는 게 더 효율적임
const T는 복사하고,const T&는 참조만 함.
복사비용이 큰 객체일수록const T&가 빠르고 메모리 절약됨!
아주 중요한 질문이에요!
const와 &(참조)의 필요 여부를 정확히 아는 건 함수 작성의 기본입니다.
아래에 언제 필요한지, 언제 안 써도 되는지를 명확히 정리해드릴게요.
const가 필요한 경우 vs 필요 없는 경우함수 안에서 매개변수를 수정하지 않아야 할 때
void print(const std::string& msg) {
std::cout << msg;
}
실수로 값 바꾸는 것을 방지하고 싶을 때
임시 객체를 전달받을 때도 허용하고 싶을 때
print("Hello"); // const 없으면 string temp = "Hello"; 복사 발생
그 값을 함수 안에서 직접 변경할 목적일 때
void addOne(int& x) { x += 1; } // const ❌
함수 안에서 복사해도 되는 값 (작은 값: int, char, double 등)
void addTen(int x) { x += 10; } // const 굳이 필요 없음
&가 필요한 경우 vs 필요 없는 경우복사 비용이 큰 타입일 때
→ string, vector, map, 사용자 정의 클래스 등
void show(const std::string& s); // ✅ 복사 안 하면서 읽기만
함수 안에서 원본을 직접 수정할 때
void modify(int& x); // ✅ 진짜 값을 바꿔야 할 때
작은 값 타입 (int, float, char 등)이고, 수정 안 하고, 복사해도 부담 없을 때
void print(int x); // 그냥 값으로 받아도 무방
값을 복사해도 되고, 함수 안에서 그 복사본만 쓸 때
| 상황 | const 필요 | 참조(&) 필요 | 추천 형태 |
|---|---|---|---|
| 값 변경 없이 읽기만 | ✅ | ✅ (클래스일 때) | const T& |
| 원본을 수정해야 할 때 | ❌ | ✅ | T& |
| 값이 작고 복사해도 부담 없을 때 | ❌ | ❌ | T |
| 임시 객체를 받기 위해 | ✅ | ✅ | const T& |
읽기 전용이고 큰 자료형이면 → const T&수정이 목적이면 → T&작은 자료형이면 → T