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

C++11 주요 업데이트 : std::regex, Type Traits, Uniform Initialization

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

C++11 주요 업데이트 : std::regex, Type Traits, Uniform Initialization
C++11 주요 업데이트 : std::regex, Type Traits, Uniform Initialization

 

🔖 INDEX

     

     

    정규 표현식 라이브러리: std::regex

    C++11에서 도입된 std::regex 라이브러리는 정규 표현식의 파싱, 검색, 그리고 문자열 조작을 위한 강력한 도구들을 제공합니다. 아래에 이 라이브러리의 주요 내용을 요약하여 설명하겠습니다.

     

    주요 컴포넌트

    • std::regex: 정규 표현식 객체입니다. 이 객체는 정규 표현식 패턴을 나타냅니다.
    • std::smatch: 문자열 검색의 결과로 반환되는 match 객체입니다.
    • std::regex_iterator: 주어진 문자열에서 정규 표현식과 일치하는 부분을 반복적으로 검색하는 반복자입니다.
    • std::regex_token_iterator: 반복자와 유사하나, 정규 표현식의 서브매치나 토큰을 반복적으로 검색합니다.

     

    주요 함수

    • std::regex_match: 주어진 문자열이 정규 표현식과 전체적으로 일치하는지 확인합니다.
    • std::regex_search: 주어진 문자열에서 정규 표현식과 일치하는 부분이 있는지 검색합니다.
    • std::regex_replace: 문자열에서 정규 표현식과 일치하는 부분을 다른 문자열로 교체합니다.

     

    사용 예제

    #include <iostream>
    #include <regex>
    #include <string>
    
    int main() {
        std::string input = "My email is example@gmail.com and my friend's email is friend@yahoo.com";
        
        // Email 정규 표현식 패턴
        std::regex email_pattern(R"(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b)");
    
        // 문자열에서 email 패턴과 일치하는 모든 부분을 찾아 출력
        std::sregex_iterator begin = std::sregex_iterator(input.begin(), input.end(), email_pattern);
        std::sregex_iterator end;
        for (std::sregex_iterator i = begin; i != end; ++i) {
            std::smatch match = *i;
            std::string match_str = match.str();
            std::cout << "Found email: " << match_str << '\n';
        }
    
        // Email 주소를 [REDACTED]로 교체
        std::string replaced = std::regex_replace(input, email_pattern, "[REDACTED]");
        std::cout << "Replaced string: " << replaced << '\n';
    
        return 0;
    }

     

    주의 사항

    • std::regex는 일부 구현에서 성능 문제가 있을 수 있습니다. 특히 복잡한 패턴이나 큰 입력 문자열에서는 성능 이슈가 나타날 수 있으므로, 실제 사용 시에는 성능 테스트를 통해 확인해야 합니다.
    • 정규 표현식 자체가 복잡하므로, 의도한 대로 동작하는지 항상 확인해야 합니다.

     

     

    Type Traits

    타입 특성(Type Traits)는 C++ 표준 라이브러리의 일부로, 타입에 대한 정보를 컴파일 시간에 조회하거나 타입 변환을 수행하는 역할을 합니다. 이는 메타프로그래밍, 템플릿 프로그래밍, SFINAE 같은 고급 기술에서 매우 유용합니다.

     

    주요 타입 특성

    • Type Relationships:
      • std::is_same<T, U>: 두 타입이 동일한지 확인.
      • std::is_base_of<Base, Derived>: Derived 타입이 Base의 파생 클래스인지 확인.
    • Type Properties:
      • std::is_void<T>: 타입이 void인지 확인.
      • std::is_integral<T>: 타입이 정수형 (예: int, char 등)인지 확인.
      • std::is_floating_point<T>: 타입이 실수형 (예: float, double, long double)인지 확인.
      • std::is_pointer<T>: 타입이 포인터인지 확인.
      • std::is_reference<T>: 타입이 참조형인지 확인
      • ... 그 외 다양한 특성들.
    • Type Modifiers:
      • std::remove_reference<T>: 참조를 제거한 타입을 반환.
      • std::add_const<T>: 상수 타입을 반환.

     

    사용 예제

    #include <iostream>
    #include <type_traits>
    
    int main() {
        if (std::is_integral<int>::value) {
            std::cout << "int is an integral type.\n";
        }
    
        if (std::is_same<std::remove_reference<int&>::type, int>::value) {
            std::cout << "Removing reference from int& gives int.\n";
        }
    
        return 0;
    }

     

    주요 이점

    • 컴파일 시간 최적화: 타입 특성을 사용하여 컴파일 시간에 적절한 코드 경로를 선택하거나 불필요한 코드를 제거할 수 있습니다.
    • 타입 안정성: 코드가 예상된 타입에만 동작하도록 보장합니다. 이를 통해 런타임 에러의 위험을 줄일 수 있습니다.
    • 유연한 템플릿 코드 작성: 타입 특성을 사용하여 다양한 타입에 대응하는 유연한 템플릿 코드를 작성할 수 있습니다.

     

    주의 사항

    • 타입 특성은 컴파일 시간의 메타프로그래밍 도구로서, 런타임의 오버헤드가 없습니다. 그러나 복잡한 템플릿 코드에서 너무 많이 사용하면 컴파일 시간이 길어질 수 있습니다.

     

     

    Uniform Initialization

    C++11에서 도입된 유니폼 초기화 (Uniform Initialization)는 초기화 프로세스를 단순화하고 일관성을 높이기 위한 방법입니다. 중괄호 {}를 사용하여 대부분의 타입의 객체를 초기화할 수 있습니다.

     

    기본적인 이점

    • 일관성: 여러 초기화 스타일이 필요하지 않으므로 초기화 과정이 더 간결하고 예측 가능해집니다.
    • 보다 안전: 가장 좁은 타입으로의 자동 변환을 방지하여 초기화 중 오류를 줄입니다.
    • 집합 초기화의 확장: 일반 객체뿐만 아니라 컨테이너와 같은 복잡한 데이터 구조도 초기화할 수 있습니다.

     

    사용 예제

    기본 타입의 초기화

    int i{3};
    double d{2.5};
    char c{'a'};

     

    클래스 및 구조체

    class MyClass {
    public:
        int x;
        double y;
    };
    
    MyClass obj{5, 3.5};

     

    컨테이너와 배열

    std::vector<int> v{1, 2, 3, 4, 5};
    int arr[]{1, 2, 3, 4};

     

    동적 메모리 할당

    auto ptr = new int[]{1, 2, 3};

     

    주의 사항

    초기화에 대한 모호성

    몇몇 초기화 시나리오에서, 유니폼 초기화와 전통적인 초기화 방법이 충돌할 수 있습니다.

    std::vector<int> v(10, 2);  // 2로 초기화된 10개의 원소를 가진 벡터
    std::vector<int> w{10, 2}; // 10과 2 두 개의 원소를 가진 벡터

     

    직접 초기화와 복사 초기화

    유니폼 초기화는 복사 초기화에서 일부 제약 사항을 피하려고 직접 초기화를 사용합니다.

    class MyClass {
    public:
        MyClass(int) {}
    };
    
    MyClass obj1{42};  // OK
    MyClass obj2 = {42}; // OK in C++11 with uniform initialization

     

     

    댓글