사용자 정의 리터럴

Jaemyeong Lee·2024년 8월 20일
0

FastCampusC++

목록 보기
67/78

C++ 사용자 정의 리터럴 분석 및 정리

이번 포스트에서는 C++에서 사용자 정의 리터럴(User-defined literals)을 사용하는 방법과 이들의 정의에 대해 알아보겠습니다. 사용자 정의 리터럴은 특정 접미사를 사용하여 특정 타입의 값을 생성할 수 있게 해주는 기능입니다. 예제 코드를 통해 이러한 개념들을 한 줄 한 줄 분석해 보겠습니다.

코드 분석

#include <iostream>
#include <chrono>
  • 헤더 파일 포함:
    • iostream: 표준 입출력 스트림을 위한 헤더 파일입니다.
    • chrono: 시간 관련 기능을 제공하는 표준 라이브러리로, std::chrono::duration과 같은 시간 단위들을 다룹니다.
using namespace std;
  • 네임스페이스 사용:
    • 표준 라이브러리의 네임스페이스를 전역적으로 사용합니다.

Length 클래스 정의

class Length
{
private:
    const long double _value;
    Length(long double value) : _value(value)
    {

    }
  • Length 클래스:
    • 길이를 나타내는 단위(미터, 킬로미터, 밀리미터, 센티미터)를 표현하는 클래스입니다.
    • _value: 길이의 값을 저장하는 long double 타입의 상수 멤버 변수입니다.
    • 생성자 Length(long double value): 주어진 값을 _value에 저장하는 private 생성자입니다. private으로 설정되어 외부에서 직접 생성할 수 없고, 사용자 정의 리터럴을 통해서만 객체를 생성할 수 있습니다.
    friend Length operator"" _m(unsigned long long value);
    friend Length operator"" _m(long double value);
    friend Length operator"" _km(unsigned long long value);
    friend Length operator"" _km(long double value);
    friend Length operator"" _mm(unsigned long long value);
    friend Length operator"" _mm(long double value);
    friend Length operator"" _cm(unsigned long long value);
    friend Length operator"" _cm(long double value);
  • 친구 함수 선언:
    • 여러 사용자 정의 리터럴(_m, _km, _mm, _cm)을 클래스 외부에서 정의할 수 있게끔 Length 클래스의 친구 함수로 선언합니다. 이를 통해 이 함수들은 클래스의 private 멤버에 접근할 수 있습니다.
public:
    long double m() const { return _value; }
    long double km() const { return _value * 0.001; }
    long double mm() const { return _value * 1000; }
    long double cm() const { return _value * 100; }
  • 단위 변환 메서드:
    • m(): _value를 미터 단위로 반환합니다.
    • km(): _value를 킬로미터 단위로 변환하여 반환합니다.
    • mm(): _value를 밀리미터 단위로 변환하여 반환합니다.
    • cm(): _value를 센티미터 단위로 변환하여 반환합니다.
    Length operator+() const
    {
        return Length(_value);
    }

    Length operator-() const
    {
        return Length(-_value);
    }

    Length operator+(const Length& length) const
    {
        return Length(_value + length._value);
    }

    Length operator-(const Length& length) const
    {
        return Length(_value - length._value);
    }
};
  • 연산자 오버로딩:
    • operator+(): 양수 값을 반환하는 단항 + 연산자입니다.
    • operator-(): 음수 값을 반환하는 단항 - 연산자입니다.
    • operator+(const Length& length): 두 Length 객체의 값을 더하는 이항 + 연산자입니다.
    • operator-(const Length& length): 두 Length 객체의 값을 빼는 이항 - 연산자입니다.

사용자 정의 리터럴 함수

Length operator"" _m(unsigned long long value)
{
    return Length(value);
}

Length operator"" _m(long double value)
{
    return Length(value);
}
  • _m 사용자 정의 리터럴:
    • operator"" _m(unsigned long long value): 정수 타입의 값을 받아 미터 단위의 Length 객체를 생성합니다.
    • operator"" _m(long double value): 부동소수점 타입의 값을 받아 미터 단위의 Length 객체를 생성합니다.
Length operator"" _km(unsigned long long value)
{
    return Length(value * 1000L);
}

Length operator"" _km(long double value)
{
    return Length(value * 1000L);
}
  • _km 사용자 정의 리터럴:
    • operator"" _km(unsigned long long value): 정수 타입의 값을 받아 킬로미터를 미터로 변환하여 Length 객체를 생성합니다.
    • operator"" _km(long double value): 부동소수점 타입의 값을 받아 킬로미터를 미터로 변환하여 Length 객체를 생성합니다.
Length operator"" _mm(unsigned long long value)
{
    return Length(value * 0.001L);
}

Length operator"" _mm(long double value)
{
    return Length(value * 0.001L);
}
  • _mm 사용자 정의 리터럴:
    • operator"" _mm(unsigned long long value): 정수 타입의 값을 받아 밀리미터를 미터로 변환하여 Length 객체를 생성합니다.
    • operator"" _mm(long double value): 부동소수점 타입의 값을 받아 밀리미터를 미터로 변환하여 Length 객체를 생성합니다.
Length operator"" _cm(unsigned long long value)
{
    return Length(value * 0.01L);
}

Length operator"" _cm(long double value)
{
    return Length(value * 0.01L);
}
  • _cm 사용자 정의 리터럴:
    • operator"" _cm(unsigned long long value): 정수 타입의 값을 받아 센티미터를 미터로 변환하여 Length 객체를 생성합니다.
    • operator"" _cm(long double value): 부동소수점 타입의 값을 받아 센티미터를 미터로 변환하여 Length 객체를 생성합니다.

main 함수 설명

int main()
{
    // 표준 라이브러리에서 사용하는 사용자 정의 리터럴
    chrono::minutes m = 24h + 5min;
    cout << m.count() << endl;
  • 표준 라이브러리의 사용자 정의 리터럴:
    • 24h5min은 C++ 표준 라이브러리 chrono에서 제공하는 시간 단위 사용자 정의 리터럴입니다.
    • chrono::minutes m = 24h + 5min;은 24시간과 5분을 더한 값을 분 단위로 계산합니다. 결과는 m.count()를 통해 출력됩니다.
    Length len = 1_m + 1_km + 1_cm + 1_mm;
    cout.precision(16);
    cout << len.m() << endl;
    cout << len.km() << endl;
    cout << len.cm() << endl;
    cout << len.mm() << endl;
}
  • 사용자 정의 리터럴의 활용:
    • Length len = 1_m + 1_km + 1_cm + 1_mm;: 1미터, 1킬로미터, 1센티미터, 1밀리미터를 더하여 Length 객체를 생성합니다.
    • cout.precision(16);: 출력 시 소수점 이하 16자리까지 표현되도록 설정합니다.
    • cout << len.m() << endl;: len 객체의 길이를 미터 단위로 출력합니다.
    • cout << len.km() << endl;: len 객체의 길이를 킬로미터 단위로 출력합니다.
    • cout << len.cm() << endl;: len 객체의 길이를 센티미터 단위로 출력합니다.
    • cout << len.mm() << endl;: len 객체의 길이를 밀리미터 단위로 출력합니다.

사용자 정의 리터럴의 정의와 사용 방법

  • 정의 방법:

    • 사용자 정의 리터럴은 operator"" 키워드를 사용하여 정의됩니다.
    • 함수 이름 뒤에 붙는 리터럴 접미사(예: _m, _km)를 통해 특정 타입의 값을 생성할 수 있습니다.
    • 정수형(unsigned long long) 또는 부동소수점(long double) 값을 매개변수로 받아 처리할 수 있습니다.
  • 사용 방법:

    • 정의된 리터럴

을 사용하면, 해당 접미사를 사용하여 객체를 생성할 수 있습니다. 예를 들어, 1_m, 1_km와 같은 표현은 각각 미터와 킬로미터 단위의 Length 객체를 생성합니다.

  • 이러한 리터럴을 사용하면 코드의 가독성이 높아지고, 단위 변환과 같은 작업을 보다 명확하게 표현할 수 있습니다.

결론

이 포스트에서는 C++에서 사용자 정의 리터럴을 정의하고 사용하는 방법에 대해 살펴보았습니다. 사용자 정의 리터럴은 특정 단위나 타입을 보다 직관적으로 표현할 수 있도록 도와주며, 특히 단위 변환이나 시간 계산 등에서 유용하게 활용될 수 있습니다. 이번 예제를 통해 사용자 정의 리터럴의 개념을 이해하고 실무에 적용할 수 있기를 바랍니다!

profile
李家네_공부방

0개의 댓글