다음의 C++20에 추가된 기능을 살펴보겠습니다.

  1. Designated Initialization(지정된 초기화)
  2. Constexpr
  3. Consteval
  4. ETC…

Designated Initialization 지정된 초기화

Aggregate 초기화를 사용 할 때 명시적으로 멤버의 이름을 지정하여 초기화 하는 것

class Point3
{
    int x, y, z;
}

int main()
{
    //C++17
    Point p0 = {1, 2, 3};
    
    //C++20
    Point p1 = {.x = 1, .y = 2, .z = 3};
    Point p2 = {.x = 1, .z = 3}; // y는 0으로 초기화 됨
    
    //C++20 부터는 클래스의 생성자가 없어도 하단 문법이 정상 처리됨
    Point p3(1, 2, 3);
    Point p4(1); //1, 0, 0
    
    //주의 사항
    Point p5 = {.y = 2, .x = 1}; // C++20에서 지정된 초기화의 멤버 순서가 바뀔 경우 오류 발생
    Point p6 = {.x = 1, 2}; // 섞어서 쓸 경우 오류 발생
}

Constexpr 관련 변경점

  • std::is_constant_evaluated() 함수 추가 : 어떤 함수가 컴파일 타임에 실행 되는지 여부
  • constexpr virtual function : 가상 함수도 constexpr 사용 가능 (17 이전에는 불가능)
  • std 알고리즘에 constexpr 지원
//constexpr : 컴파일 시간 또는 실행시간에 수행 될 수 있다
#include <algoritm>
#include <numeric>
#include <array>

constexpr auto add(int x, int y)
{
    bool isCompileTime = std::is_constant_evaluated();
    return std::pair(x+y, isCompileTime);
}

int main()
{
    //is_constant_evaluated 관련
    constexpr auto a = add(1, 2); // true
    auto b = add(1, 2); // false;
    
    int x = 1, y = 2;
  	auto c = add(x, y); // false
    constexpr auto d = add(x, y); // 컴파일 에러 : 해당 표현은 컴파일 타임에 실행 될 수 없기에 constexpr를 제거해야 한다.
    
    
    // std 알고리즘 관련 변화
    constexpr int x[3] = {1, 2, 3};
    //하단 std 컨테이너들도 constexpr 형으로 20 표준에서 지원 예정에 있다고 한다. 현재(2021-1-6)까지 아직 오류 발생
    //constexpr std::array<int, 3> x = {1, 2, 3};
    //constexpr std::vector<int, 3> x = {1, 2, 3};
    
    constexpr int aa = std::accumulate(std::begin(x), std::end(x), 0); // std 알고리즘이 컴파일 타임에 계산되어 성능 최적화가 가능
    constexpr auto gotIt = std::find(std::begin(x), std::end(x), 3); // std 알고리즘이 컴파일 타임에 계산되어 성능 최적화가 가능
}

신규 키워드 consteval

함수가 반드시 컴파일 시간에만 수행 될 수 있음을 명시(immediate function)

consteval int Add(int a, int b) { return a + b; }

int main()
{
    int x = 1, y = 3;
    
    int a = add(x, y); // 컴파일 에러
    int b = add(1, 2); // 성공
}

C++20 추가된 간단한 문법들

  • explicit(bool) explicit 키워드를 사용시 적용 여부를 지정 할 수 있다.

    //explicit 의미 : 복사 생성자 사용 불가, 생성자를 사용한 암시적 변환 불가
    
    template<typename T> class Hello
    {
        T data;
    public:
        explicit( std::is_integral_v<T> ) Hello(T v) : data(v) // 정수형 일 때만 explicit가 적용되도록 구현 가능
    }
    
  • ranged-for with initializer range for에 초기화 구문 표현이 가능

    // 다음과 같은 표현이 가능해짐 C++20
    for( int y[3]{1,2,3}; auto n : y)
    {
    
    }
    
    while ( int n = 0; n < 10) // while은 문법 오류
    {
    
    }
    
  • using enum enum class 사용시 namespace 없이 사용 가능해짐

    enum class Color
    {
     	red = 1,
        green = 2,
        blue = 3
    };
    
    int main()
    {
        Color temp = color::red;
    
        switch(temp)
        {
            //case color::red: return 1;
            //case color::green: return 2;
    
            //다음과 같이 사용 할 경우 namespace 생략 가능해짐
            using enum Color;
            case red: return 1;
            case green: return 2;
        }
    }
    

더 많은 C++20 관련 정보