본문 바로가기
프로그래밍/C++

C++11 주요 업데이트 : Deleted Functions, User-defined Literals, constexpr

by 머니테크리더 2023. 10. 3.
반응형

C++11 주요 업데이트 : Deleted Functions, User-defined Literals, constexpr
C++11 주요 업데이트 : Deleted Functions, User-defined Literals, constexpr

 

🔖 INDEX

     

     

    Deleted Functions

    C++11에서는 함수를 명시적으로 삭제할 수 있는 기능이 도입되었습니다. 함수를 삭제하는 것은 해당 함수가 사용되는 것을 방지하기 위한 것입니다. 함수를 삭제하면 해당 함수에 대한 모든 호출은 컴파일 시간에 오류로 간주됩니다.

    이 기능은 클래스 설계에서 특히 유용하며, 개발자가 해당 함수가 사용되지 않도록 의도적으로 선택할 수 있습니다. 이전의 C++ 버전에서는 이를 달성하기 위해 함수를 private으로 만들거나 구현을 제공하지 않았지만, C++11에서는 delete 키워드를 사용하여 이를 명시적으로 표현할 수 있습니다.

     

    사용 예제

    복사 생성자 및 대입 연산자 삭제

    클래스가 복사되는 것을 원하지 않는 경우, 복사 생성자와 대입 연산자를 삭제할 수 있습니다.

    class NonCopyable {
    public:
        NonCopyable() {}
        NonCopyable(const NonCopyable&) = delete;            // 복사 생성자 삭제
        NonCopyable& operator=(const NonCopyable&) = delete; // 복사 대입 연산자 삭제
    };

     

    특정 오버로드 함수 삭제

    특정 매개 변수 타입에 대한 함수 오버로드를 삭제할 수 있습니다.

    class MyClass {
    public:
        void process(double value) { /* ... */ }
        void process(int) = delete;  // int 형식에 대한 오버로드 삭제
    };

     

    주요 이점

    • 설계 의도 명확성: 함수를 명시적으로 삭제하면 해당 클래스의 사용 방법에 대한 설계 의도가 더 명확해집니다.
    • 컴파일 시간 오류: 함수를 삭제하면 그 함수를 호출하는 코드는 컴파일되지 않습니다. 이를 통해 런타임 에러를 피하고 컴파일 시간에 문제를 발견할 수 있습니다.
    • 개선된 코드 읽기성: 함수가 삭제되었다는 것을 명시적으로 표시하면 코드의 읽기성이 향상됩니다.

     

     

    User-defined Literals

    C++11에서 도입된 사용자 정의 리터럴을 통해 개발자가 리터럴 연산자를 정의하고 새로운 리터럴 형식을 만들 수 있게 되었습니다. 사용자 정의 리터럴을 사용하면 코드의 가독성과 표현력을 향상시킬 수 있습니다.

     

    기본 구조

    return_type operator"" _suffix(arguments)
    • _suffix: 리터럴의 접미사입니다. 항상 밑줄로 시작해야 합니다.
    • arguments: 리터럴 값이 전달될 인수입니다.
    • return_type: 리터럴 연산자의 반환 타입입니다.

     

    사용 예제

    단위 변환

    시간, 거리, 무게 등의 단위를 변환하는 데 사용자 정의 리터럴을 사용할 수 있습니다.

    long double operator"" _cm(long double x) {
        return x * 10;
    }
    
    long double operator"" _m(long double x) {
        return x * 1000;
    }
    
    int main() {
        long double height = 185_cm;
        long double distance = 1.5_m;
        // height는 1850, distance는 1500
    }

     

    복소수 표현

    복소수 리터럴을 사용자 정의 리터럴로 정의할 수 있습니다.

    #include <complex>
    
    std::complex<double> operator"" _i(long double imaginary) {
        return std::complex<double>(0, imaginary);
    }
    
    int main() {
        auto complex_num = 4.2 + 3.5_i;
        // complex_num는 (4.2, 3.5)의 복소수
    }

     

    주요 유의 사항

    • 리터럴 접미사는 항상 밑줄(_)로 시작해야 합니다. 이는 표준 리터럴과 충돌을 방지하기 위한 것입니다.
    • 표준 라이브러리는 이미 일부 사용자 정의 리터럴을 제공하므로 (예: std::chrono의 시간 관련 리터럴), 이러한 리터럴의 중복 정의를 피해야 합니다.

     

     

    constexpr (Compile-Time Expression)

    C++11에서 도입된 constexpr는 컴파일 시간에 값을 계산할 수 있는 상수나 함수를 정의하는 데 사용되는 키워드입니다. 이를 통해 런타임 오버헤드 없이 값의 계산이나 상수의 정의를 컴파일 시간에 수행할 수 있습니다.

     

    주요 특징

    • 컴파일 시간 계산: constexpr 키워드를 사용하여 정의된 변수나 함수는 컴파일 시간에 계산됩니다.
    • 상수 표현식: constexpr로 정의된 변수는 상수 표현식이어야 합니다. 즉, 그 값은 컴파일 시간에 알려져 있어야 합니다.
    • 간단한 함수: 초기의 C++11에서, constexpr 함수는 매우 제한적이었습니다. 바디에는 단일 return문만 있어야 했습니다. 그러나 C++14부터는 이 제한이 풀려, 조건문, 루프, 여러 문장 등을 포함할 수 있게 되었습니다. 그러나 여전히 모든 경로에서 컴파일 시간에 값을 계산할 수 있어야 합니다.

     

    사용 예제

    컴파일 시간 상수

    constexpr int value = 5 * 5;  // 컴파일 시간에 계산됨
    int arr[value];               // 고정 크기 배열에 사용될 수 있음

     

    컴파일 시간 함수

    constexpr int factorial(int n) {
        return (n <= 1) ? 1 : n * factorial(n - 1);
    }
    
    int main() {
        constexpr int result = factorial(5);  // 컴파일 시간에 계산됨, result는 120
    }

     

    주요 이점

    • 성능: 런타임에 추가적인 계산이 필요하지 않기 때문에 constexpr는 성능 향상에 도움이 될 수 있습니다.
    • 안전성: 컴파일 시간에 값이 계산되기 때문에, 런타임 에러를 줄일 수 있습니다. 특히 배열의 크기나 템플릿 인자 같은 곳에서 컴파일 시간 상수가 필요한 경우 유용합니다.

     

     

    댓글