728x90

1. 템플릿 람다 정의

  • 템플릿 매개변수를 가진 람다.

 

2. C++ 11, C++14, C++ 20에 추가된 람다 비교

C++ 11 형식 있는 람다 ( Typed Lambda ) 람다 식에 사용한 매개변수로 형 변환이 가능한 형식들만 사용 가능
C++ 14 일반적 람다 ( Generic Lambda ) 모든 형식 사용 가능
C++ 20 템플릿 람다 ( Template Lambda ) 템플릿에 사용한 형식과 반드시 같아야 함

 

3. 사용 방법

    // C++ 11
    auto addInt = []( int InA, int InB ) { return InA + InB; };
    std::cout << addInt( 10, 20    ) << std::endl;
    std::cout << addInt( 10, 20.0f ) << std::endl; // 20.f 값을 int로 형 변환 가능

    // C++ 14
    auto addAuto = []( auto InA, auto InB ) { return InA + InB; };
    std::cout << addAuto( 10, 20   ) << std::endl;
    std::cout << addAuto( 10, 20.f ) << std::endl; // 모든 형식 사용 가능

    // C++ 14
    auto addDeclType = []( auto InA, decltype( InA ) InB ) { return InA + InB; };
    std::cout << addDeclType( 10, 20 ) << std::endl;
    std::cout << addDeclType( 10, 20.f ) << std::endl; // 20.f 값을 int로 형 변환 가능

    // C++ 20
    auto addTypeName = []< typename T >( T InA, T InB ) { return InA + InB; };
    std::cout << addTypeName( 10, 20 ) << std::endl;
    //std::cout << addTypeName( 10, 20.f ) << std::endl; // 첫 형식과 다르므로 컴파일 에러
  • decltype ( auto ) C++ 14에 추가된 타입 추론 키워드이다.
  • decltype ( 추론하고자 하는 타입 )

 

4. 람다 표현식 만드는 방법

  • 1. capture 절 ( lambda - introducer )
  • 2. 매개 변수 목록 필드
  • 3. 변경 가능한 사양 필드, () 연산자 함수를 비 상수 함수로 만들 수 있다.
  • 4. 예외 사양 필드
  • 5. 후행 반환 형식 필드
  • 6. 람다 본문

 

[참고]

https://docs.microsoft.com/ko-kr/cpp/cpp/lambda-expressions-in-cpp?view=msvc-170

https://docs.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=msvc-170

반응형

'C++ > C++ 20' 카테고리의 다른 글

[C++ 20] std::erase_if 를 이용한 요소 삭제  (0) 2022.02.25
[C++ 20] std::span  (0) 2022.02.25
[C++ 20] consteval, constinit 지정자  (0) 2022.02.23
[C++20] 지명 초기화  (0) 2022.02.22
[C++ 20] 삼항 연산자 <=>  (0) 2022.02.20
728x90

1. consteval 정의

  • 즉시 함수를 생성하는 지정자, 해당 함수가 컴파일 시점에 평가된다.

2. consteval 사용 방법

  • 소멸자, 메모리 할당, 재할당 함수에는 consteval를 적용할 수 없다.
  • 하나의 함수 선언에 consteval과 constexpr, constinit 중 하나만 사용할 수 있다.
  • consteval 지정자가 붙은 함수는 암묵적으로 인라인 함수가 되며, constexpr 함수의 요구 조건이 충족돼야 한다.
// consteval 지정자를 사용한 즉시 함수 
consteval int Add( int InA, int InB )
{
    return InA + InB;
}

int main()
{
    // 상수 표현식 사용
    std::cout << Add( 10, 20 ) << std::endl;

    // const 상수 표현식 사용
    const int a = 10;
    std::cout << Add( a, 20 ) << std::endl;

    // 비상수 사용
    int b = 20;
    std::cout << Add( 10, b ) << std::endl;
}

3. constexpr 허용된 조건

  • 조건부 점프 문과 반복 문
  • 하나 이상의 문장
  • constexpr 함수 호출, consteval 함수는 오직 constexpr 함수만 호출할 수 있다. ( 컴파일 시점에 확인 가능한 함수 )
  • 상수 표현식으로 초기화한 기본 형식의 변수.

4. constexpr 허용되지 않는 조건

  • static 변수와 thread_local 변수
  • try 블록과 goto 문
  • none consteval 함수의 호출, none constexpr 변수의 사용

 

5. constinit 정의

  • 변수가 컴파일 시점에 초기화 되도록 하는 지정자.
  • 정적 저장 기간, 스레드 저장 기간에 constinit을 붙인다고 해서 상수 변수가 되는 것은 아니니 유의하자!

6. constinit 사용 방법

  • 전역 변수, 정적 변수, 정적 클래스 멤버 등 저장 기간이 정적인 변수( static 변수 )에 사용 가능하다.
  • 스레드 지역 변수에 사용 가능 하다.
// consteval 지정자를 사용한 즉시 함수 
consteval int Add( int InA, int InB )
{
    return InA + InB;
}

constexpr auto ResultA = Add( 10, 20 );
constinit auto ResultB = Add( 10, 20 );

int main()
{
    // 정적 기간 변수 사용
    std::cout << ResultA << std::endl;
    std::cout << ResultB << std::endl;

    // 스레드 지역 변수 사용
    constinit thread_local auto resultC = Add( 10, 20 );
    std::cout << resultC << std::endl;
}
반응형

'C++ > C++ 20' 카테고리의 다른 글

[C++ 20] std::span  (0) 2022.02.25
[C++ 20] 템플릿 람다  (0) 2022.02.23
[C++20] 지명 초기화  (0) 2022.02.22
[C++ 20] 삼항 연산자 <=>  (0) 2022.02.20
[C++ 20] 모듈 ( Module )  (0) 2022.02.20
728x90

1. 지명 초기화 정의

  • 집합체( 배열, 클래스, 구조체, 공용체 ) 초기화의 한 특수 사례이다.

2. 집합체 초기화 조건

  • private 멤버, protected 멤버, 비정적 데이터 멤버가 존재하지 않다.
  • 사용자 정의 생성자나 상속된 생성자가 없다.
  • 가상, 비공개, 보호된 기반 클래스가 없다.
  • 가상 멤버 함수가 없다.

3. 사용 방법

  • 중괄호를 사용하여 멤버들의 값을 초기화시켜준다.
  • 중괄호 한 초기치들의 순서는 해당 멤버들의 선언 순서와 일치해야 한다.
  • 축소 변환이 발생하면 컴파일러는 컴파일 오류를 발생시킨다.
반응형

'C++ > C++ 20' 카테고리의 다른 글

[C++ 20] 템플릿 람다  (0) 2022.02.23
[C++ 20] consteval, constinit 지정자  (0) 2022.02.23
[C++ 20] 삼항 연산자 <=>  (0) 2022.02.20
[C++ 20] 모듈 ( Module )  (0) 2022.02.20
[C++ 20] 프로그램 빌드 과정 및 문제점  (0) 2022.02.19
728x90

기존 로직 : strlen을 이용한 빈 문자열 체크

// 파일 경로 유효성 검사 확인 함수
bool FileExistA( const char* InPath )
{
    if ( strlen( InPath ) == 0 ) return false;

    bool bResult = false;
    /*
        경로 확인 함수 내용...
        bResult  = ...
    */
    return bResult;
}

 

개선 로직 : strcmp를 이용한 빈 문자열 체크

// 파일 경로 유효성 검사 확인 함수
bool FileExistB( const char* InPath )
{
    if ( strcmp( InPath, "\0") == 0 ) return false;

    bool bResult = false;
    /*
        경로 확인 함수 내용...
        bResult  = ...
    */
    return bResult;
}

 

성능 확인 : 200,000,000 회 진행 시 약 2배 차이

int main()
{
    time_t startTime;
    time_t endTime;

    time( &startTime );
    for ( int count = 0; count < 200000000; ++count )
    {
        FileExistA( "FileExistTest/Test/Test/ItemIcon" );
        FileExistA( "" );
    }
    time( &endTime );
    double diffTimeA = difftime( endTime, startTime );

    time( &startTime );
    for ( int count = 0; count < 200000000; ++count )
    {
        FileExistB( "FileExistTest/Test/Test/ItemIcon" );
        FileExistB( "" );
    }
    time( &endTime );
    double diffTimeB = difftime( endTime, startTime );
}

결과

strlen을 이용한 함수의 경우 6초, strcmp를 이용한 함수의 경우 3초의 결과가 나왔다.

strlen를 사용한 함수의 경우 문자열을 순회한 결과로 빈 문자열을 체크하지만,

strcmp를 사용한 함수의 경우 null 문자와만 비교해 빠르게 빈 문자열 체크가 가능했다.

 

UE4 게임 프로젝트에 사용된 소스 중 일부를 빼내서 작성한 내용입니다.

실제 소스는 TCHAR* 문자열을 사용해 빈 문자열을 체크하고 있었으며,

1차 개선은 strcmp를 이용한 리팩토링

2차 개선은 FString으로 형변환 해주는 소스에서 FString::IsEmpty()를 이용한 리팩토링으로 진행.

 

이런 리팩토링이 모여 1 프레임이라도 올라갔으면 좋겠다...

 

https://en.cppreference.com/w/cpp/string/byte/strlen

https://en.cppreference.com/w/cpp/string/byte/strcmp

반응형

+ Recent posts