[2026] C++ User-Defined Literals Complete Guide | Custom Suffix Operators

[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

  1. User-defined literals: Custom suffix operators
  2. operator"": Define literal operators
  3. Types: Integer, float, string, character, raw
  4. constexpr: Compile-time evaluation
  5. Namespace: Avoid name collisions
  6. Standard library: Use built-in literals when available

Literal Operator Signatures

TypeSignature
Integeroperator"" _x(unsigned long long)
Floatoperator"" _x(long double)
Stringoperator"" _x(const char*, size_t)
Characteroperator"" _x(char)
Rawoperator"" _x(const char*)

Best Practices

  • Use namespaces to avoid collisions
  • Mark constexpr for 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

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.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3