[2026] C++ User-Defined Literals Complete Guide | Custom Suffix Operators
이 글의 핵심
Master C++ user-defined literals: custom suffix operators for expressive, type-safe code. Complete guide with integer, float, string, raw literals, and production patterns.
What are User-Defined Literals?
User-defined literals let you create custom suffixes for literals, making code more expressive and type-safe. 아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
// Standard literals
// 변수 선언 및 초기화
int x = 10;
double y = 3.14;
string s = "hello";
// User-defined literals
Distance d = 10_km; // Custom suffix
Angle a = 3.14_deg; // Custom suffix
auto str = "hello"_s; // std::string
Benefits:
- Type safety
- Expressive syntax
- Compile-time evaluation
- Domain-specific abstractions
Basic Syntax
User-defined literals are implemented as operator"" functions:
아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
// Integer literal
constexpr long long operator"" _km(unsigned long long value) {
return value * 1000; // Convert km to meters
}
int main() {
auto distance = 10_km; // 10000 meters
cout << distance << endl; // 10000
}
Key: The operator"" function is called with the literal value, returning the desired type.
Literal Types
1. Integer Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
constexpr unsigned long long operator"" _KB(unsigned long long value) {
return value * 1024;
}
constexpr unsigned long long operator"" _MB(unsigned long long value) {
return value * 1024 * 1024;
}
int main() {
auto size1 = 10_KB; // 10240
auto size2 = 5_MB; // 5242880
cout << size1 << ", " << size2 << endl;
}
Output:
10240, 5242880
2. Floating-Point Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
constexpr long double operator"" _deg(long double value) {
return value * 3.14159265358979323846L / 180.0L; // Degrees to radians
}
constexpr long double operator"" _rad(long double value) {
return value;
}
int main() {
auto angle1 = 90.0_deg; // π/2 radians
auto angle2 = 1.57_rad; // 1.57 radians
cout << angle1 << ", " << angle2 << endl;
}
Output:
1.5708, 1.57
3. String Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <string>
std::string operator"" _s(const char* str, size_t len) {
return std::string(str, len);
}
int main() {
auto s1 = "hello"_s; // std::string (not const char*)
auto s2 = "world"; // const char*
// s1.size() works, s2.size() doesn't
cout << s1.size() << endl; // 5
}
Key: "hello"_s creates std::string directly, avoiding implicit conversion.
4. Character Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
constexpr char operator"" _upper(char c) {
return (c >= 'a' && c <= 'z') ? c - 32 : c;
}
int main() {
char c1 = 'a'_upper; // 'A'
char c2 = 'Z'_upper; // 'Z'
cout << c1 << ", " << c2 << endl;
}
Output:
A, Z
5. Raw Literals
다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
struct Color {
unsigned char r, g, b;
};
Color operator"" _rgb(const char* str, size_t len) {
// Parse hex string like "FF5733"
unsigned int value = std::stoi(str, nullptr, 16);
return Color{
static_cast<unsigned char>((value >> 16) & 0xFF),
static_cast<unsigned char>((value >> 8) & 0xFF),
static_cast<unsigned char>(value & 0xFF)
};
}
int main() {
auto color = "FF5733"_rgb;
cout << "R:" << (int)color.r << " G:" << (int)color.g << " B:" << (int)color.b << endl;
}
Output:
R:255 G:87 B:51
Practical Examples
Example 1: Duration
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <chrono>
constexpr std::chrono::milliseconds operator"" _ms(unsigned long long value) {
return std::chrono::milliseconds(value);
}
constexpr std::chrono::seconds operator"" _s(unsigned long long value) {
return std::chrono::seconds(value);
}
void wait() {
std::this_thread::sleep_for(100_ms);
std::this_thread::sleep_for(2_s);
}
Note: std::chrono_literals already provides ms, s, min, h suffixes. Use them instead of custom ones.
Example 2: Complex Numbers
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <complex>
constexpr std::complex<double> operator"" _i(long double value) {
return std::complex<double>(0, value);
}
int main() {
auto z1 = 3.0 + 4.0_i; // 3 + 4i
auto z2 = 1.0_i; // 0 + 1i
cout << z1 << ", " << z2 << endl;
}
Output:
(3,4), (0,1)
Example 3: Binary Literals
다음은 cpp를 활용한 상세한 구현 코드입니다. 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
constexpr unsigned long long operator"" _b(const char* str, size_t len) {
unsigned long long result = 0;
for (size_t i = 0; i < len; ++i) {
if (str[i] == '1') {
result = (result << 1) | 1;
} else if (str[i] == '0') {
result = result << 1;
}
}
return result;
}
int main() {
auto value = "1010"_b; // 10 in decimal
cout << value << endl;
}
Output:
10
Example 4: JSON Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <nlohmann/json.hpp>
nlohmann::json operator"" _json(const char* str, size_t len) {
return nlohmann::json::parse(str, str + len);
}
int main() {
auto config = R"({"port": 8080, "host": "localhost"})"_json;
cout << config[port] << endl; // 8080
}
Output:
8080
Common Issues
Issue 1: Name Collision
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
// ❌ Standard library may add _km later
constexpr long long operator"" _km(unsigned long long value) {
return value * 1000;
}
// ✅ Use namespace
namespace units {
constexpr long long operator"" _km(unsigned long long value) {
return value * 1000;
}
}
using namespace units;
auto d = 10_km;
Key: Put user-defined literals in namespaces to avoid collisions.
Issue 2: Type Mismatch
아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
// ❌ Wrong parameter type
constexpr int operator"" _x(int value) { // Error!
return value * 2;
}
// ✅ Correct parameter type
constexpr int operator"" _x(unsigned long long value) {
return value * 2;
}
Key: Integer literals must use unsigned long long parameter.
Issue 3: Non-constexpr
아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
// ❌ Runtime evaluation
std::string operator"" _upper(const char* str, size_t len) {
std::string result(str, len);
for (auto& c : result) c = std::toupper(c);
return result;
}
// ✅ Compile-time evaluation
constexpr const char* operator"" _upper(const char* str, size_t len) {
// ....constexpr implementation ...
return str;
}
Key: Use constexpr for compile-time evaluation when possible.
Standard Library Literals
C++ standard library provides many useful literals:
chrono Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.
#include <chrono>
using namespace std::chrono_literals;
auto duration1 = 100ms; // milliseconds
auto duration2 = 2s; // seconds
auto duration3 = 5min; // minutes
auto duration4 = 1h; // hours
string Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.
#include <string>
using namespace std::string_literals;
auto s1 = "hello"s; // std::string
auto s2 = "world"sv; // std::string_view (C++17)
complex Literals
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.
#include <complex>
using namespace std::complex_literals;
auto z1 = 3.0 + 4.0i; // std::complex<double>
auto z2 = 1.0if; // std::complex<float>
Production Patterns
Pattern 1: Unit System
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
namespace units {
struct Distance {
double meters;
constexpr Distance(double m) : meters(m) {}
};
constexpr Distance operator"" _m(long double value) {
return Distance(value);
}
constexpr Distance operator"" _km(long double value) {
return Distance(value * 1000);
}
constexpr Distance operator"" _mi(long double value) {
return Distance(value * 1609.34);
}
}
using namespace units;
void calculateDistance() {
Distance d1 = 10_km;
Distance d2 = 5_mi;
Distance total = Distance(d1.meters + d2.meters);
cout << total.meters << " meters" << endl;
}
Pattern 2: Configuration DSL
다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
struct Config {
int port;
string host;
size_t maxConnections;
};
Config operator"" _config(const char* str, size_t len) {
// Parse config string
// Format: "port:8080,host:localhost,max:100"
Config cfg{8080, "localhost", 100};
// ....parsing logic ...
return cfg;
}
auto serverConfig = "port:8080,host:0.0.0.0,max:1000"_config;
Pattern 3: Compile-Time String Hashing
다음은 cpp를 활용한 상세한 구현 코드입니다. 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
constexpr size_t hash(const char* str, size_t len) {
size_t h = 0;
for (size_t i = 0; i < len; ++i) {
h = h * 31 + str[i];
}
return h;
}
constexpr size_t operator"" _hash(const char* str, size_t len) {
return hash(str, len);
}
switch (eventType) {
case "click"_hash:
handleClick();
break;
case "hover"_hash:
handleHover();
break;
}
Comparison: Before vs After
Before (Manual Conversion)
Distance d1 = Distance::fromKilometers(10);
Duration t1 = Duration::fromSeconds(5);
Color c1 = Color::fromHex("FF5733");
After (User-Defined Literals)
auto d1 = 10_km;
auto t1 = 5_s;
auto c1 = "FF5733"_rgb;
Benefits:
- More readable
- Less verbose
- Type-safe
- Compile-time checked
Summary
Key Points
- User-defined literals: Custom suffix operators
- operator"": Define literal operators
- Types: Integer, float, string, character, raw
- constexpr: Compile-time evaluation
- Namespace: Avoid name collisions
- Standard library: Use built-in literals when available
Literal Operator Signatures
| Type | Signature |
|---|---|
| Integer | operator"" _x(unsigned long long) |
| Float | operator"" _x(long double) |
| String | operator"" _x(const char*, size_t) |
| Character | operator"" _x(char) |
| Raw | operator"" _x(const char*) |
Best Practices
- Use namespaces to avoid collisions
- Mark
constexprfor compile-time evaluation - Use standard library literals when available
- Document custom literals clearly
- Keep literal operators simple and predictable
When to Use
- Units (distance, time, temperature)
- String types (std::string, custom strings)
- Colors and binary data
- Domain-specific types
- Configuration DSLs
Related Articles
- C++ Operator Overloading Guide
- C++ Literals Complete Guide
- C++ User-Defined Literals Deep Dive
Keywords
C++ user-defined literals, custom suffix operators, operator overloading, type safety, compile-time, constexpr
One-line summary: User-defined literals enable custom suffix operators like 10_km and "hello"_s for expressive, type-safe code with zero runtime overhead.