이 글에서는 C++의 사용자 정의 리터럴(User Defined Literals, UDL) 개념에 대해 알아보겠습니다. UDL은 C++11 버전부터 도입된 기능으로, 기존에 제한적이었던 내장 리터럴의 한계를 보완해 줍니다.
C++의 내장 리터럴
C++는 다양한 기본 타입에 대해 리터럴을 제공하지만, 그 종류는 제한적입니다.
31— 정수(Integer)3.5— 배정밀도 실수(Double)4.2F— 부동소수점(Float)'p'— 문자(Character)31ULL— 부호 없는 long long(Unsigned Long Long)0xD0— 16진수 부호 없는 정수(Unsigned Hexadecimal Integer)"pq"— 문자열(String)
사용자 정의 리터럴이 필요한 이유
내장 리터럴만으로는 표현력이 부족한 경우가 종종 있습니다. 예를 들어 무게를 저장하는 변수를 정의한다고 생각해 봅시다.
long double Weight = 3.5;
이 값이 파운드인지, 킬로그램인지, 그램인지 전혀 알 수 없습니다. 하지만 UDL을 사용하면 값에 단위를 직접 붙일 수 있어 코드의 가독성이 크게 향상되고, 컴파일 시점에 단위 변환 검증도 가능해집니다.
weight = 5.6kg; ratio = 5.6kg / 2.1lb;
위와 같은 비율 계산에서는 두 값을 같은 단위로 변환해야 하는데, UDL을 활용하면 단위 변환 과정에서 발생하는 오류나 비용을 줄일 수 있습니다.
UDL은 사용자 정의 타입(user-defined types)에 대한 리터럴뿐 아니라, 내장 타입에 대해서도 새로운 형태의 리터럴을 정의할 수 있게 해줍니다. 코딩 시간을 크게 절약해 주지는 않지만, 더 많은 연산을 컴파일 타임으로 옮길 수 있어 실행 속도가 빨라진다는 장점이 있습니다.
예제 코드
다음 구현 예제를 통해 UDL의 동작 방식을 더 잘 이해해 보겠습니다.
#include<iostream>
#include<iomanip>
using namespace std;
unsigned long long int operator"" _kb(unsigned long long int x) {
return x * 1024;
}
unsigned long long int operator"" _b(unsigned long long int x) {
return x;
}
unsigned long long int operator"" _mb(unsigned long long int x) {
return x * 1024 * 1024;
}
int main() {
unsigned long long int size = 24_kb;
cout << "Size:" << size << endl;
cout << "Few more MB:" << (size + 2_mb) << endl;
cout << "Size Div:" << (10_kb / 2_kb) << endl;
cout << "1KB = " << (8_b * 128_b) << endl;
return 0;
}실행 결과
Size:24576 Few more MB:2121728 Size Div:5 1KB = 1024
정리
사용자 정의 리터럴은 operator"" 문법을 통해 숫자나 문자열 값에 의미 있는 단위를 결합할 수 있게 해주는 강력한 기능입니다. 바이트·킬로바이트처럼 단위가 중요한 코드에서 실수를 방지하고, 컴파일 타임 상수 평가를 활용해 프로그램 성능까지 개선할 수 있습니다.