나만의 작은 도서관

[TIL][C++] 250515 MMO 서버 개발 18일차: 템플릿에서 정의한 타입 매개변수(typename)은 반드시 템플릿 인자로 넘겨주지 않아도 된다, protobuf에서 역직렬화 함수: ParseFromArray() 본문

Today I Learn

[TIL][C++] 250515 MMO 서버 개발 18일차: 템플릿에서 정의한 타입 매개변수(typename)은 반드시 템플릿 인자로 넘겨주지 않아도 된다, protobuf에서 역직렬화 함수: ParseFromArray()

pledge24 2025. 5. 16. 11:55
주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다. 

템플릿에서 정의한 타입 매개변수(typename)는 반드시 템플릿 인자로 넘겨주지 않아도 된다.

  • 템플릿 매개변수는 넘겨준 템플릿 인자를 통해 타입이 결정된다. 따라서 템플릿 매개변수가 2개라면, 반드시 템플릿 인자도 2개를 넘겨줘야 되는 줄 알았다.
// 정의
template<typename T, typename U>
void add(T a, U b) {
    return a + b;
}

// 템플릿 함수 호출
int result1 = add<int, int>(1, 2); // => 3
  • 하지만 이는 템플릿 매개변수를 명시적으로 알려줄 뿐, 컴팡일러가 추론이 가능하다면 반드시 적어줄 필요는 없다.
int result2 = add(1, 2); // => 3
  • 이렇게 C++ 컴파일러는 타입 추론(type deduction) 기능을 이용해 템플릿 인자를 넘겨주지 않아도 템플릿 매개변수의 타입을 결정한다.

주의할 점

  • C++ 컴파일러가 타입 추론 기능을 통해 템플릿 인자 없이 타입을 결정한다고는 하지만, 이는 추론이 가능한 경우에서만 유효하다. 추론이 불가능한 경우 오류가 발생한다.
template<typename T, typename U>
U convert(T value) {
    return static_cast<U>(value);
}

// 컴파일 에러: U의 타입을 추론할 수 없음.
double result = convert(5);
  • 또한 템플릿 인자를 템플릿 매개변수 개수보다 적게 넘겨주는, 즉, 일부 타입을 추론 기능에 맡기고 템플릿 인자를 생략해 버릴 수 있는데, 이 경우 중간에 있는 인자를 생략할 수는 없기 때문에 템플릿 인자를 명시적으로 지정할 때는 반드시 왼쪽에서 오른쪽 순으로 지정해야 한다.
template<typename T, typename U>
auto func(T a, U b) {
    return a + b;
}

// 컴파일 에러 발생: 첫 번째를 생략하고 두 번째만 지정할 수 없음
func<, double>(1, 2.0);  // 문법적으로 잘못됨

protobuf에서 역직렬화 함수: ParseFromArray()

  • ParseFromArray()함수는 SerializeToArray() 함수에 반대 위치에 존재하는 함수로, 데이터가 들어있는 바이트 버퍼를 인자로 받으면 패킷에 역직렬화된 데이터를 저장된다.
    • 개인적으로 reinterpret_cast랑 비슷한 방식인 듯하다.
<역직렬화>                         <직렬화>
ParseFromArray(buffer, len) <----> SerializeToArray(buffer, len)
[byte* -> obj]                     [obj -> byte*]