728x90

우리가 알고 있는 template를 선언할 때는 아래와 같다

template<typename T>

 

여기에서 typename 대신에 NonType으로 다음과 같이 사용이 가능했다.

int, enum, pointer, reference, nullptr_t 등은 기존에도 사용이 가능했다.

template<int T>

 

이번 C++20에서는 몇가지를 더 사용할 수 있게 되었다.

- Floating-point
- Literal Type (types of constexpr variables)
- String Literal

 

Floating-point를 사용하는 예제

template<double d>
auto GetDouble()
{
   return d;
}

int main()
{
    auto d1 = GetDouble<5.5>();

    return 0;
}

 

Literal Type (types of constexpr variables)을 사용하는 예제

struct ClassType
{
    constexpr ClassType(int) {}
}

template<ClassType t>
auto GetClassType()
{
    return t;
}

int main()
{
    auto t1 = GetClassType<1>();

    return 0;
}

 

String Literal

template<int N>
class StringLiteral
{
public:
    constexpr StringLiteral(char const (&str)[N])
    {
        std::copy(str, str+N, _data);
    }
    
    char _data[N];
}

template<StringLiteral str>
class ClassTemplate {};

template<StringLiteral str>
void FunctionTemplate()
{
    cout << str data << endl;
}

int main()
{
    ClassTemplate<"Hello World"> cls1;
    FunctionTemplate<"Hello">();

    return 0;
}
728x90

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

C++20 - erase, erase_if  (1) 2023.12.29
C++20 - Template Parameter for Lambda  (0) 2023.12.28
C++20 - Conditionally Explicit Constructor (조건부 Explicit 생성자)  (1) 2023.12.27
C++20 - constinit  (2) 2023.12.27
C++20 - consteval  (1) 2023.12.27
728x90

explicit 키워드는 알고 있다시피 명시적으로 생성자를 호출하겠다는 의미이다.

조건부 explicit 생성자 키워드는 template를 사용할 때 편하게 이용할 수 있을 것 같다.

 

strcut A
{
    template<typename T>
    explicit(!std::is_same<T, bool>::value) A(T t)
    {
        cout << typeid(t).name() << endl;
    }
}

void TestA(A a)
{
}

int main()
{
    A a(true);
    TestA(a);     // 기본적으로 성공
    TestA(true);  // 조건이 맞기 때문에 성공
    TestA(10);    // 조건이 틀리므로 실패
    
    return 0;
}
728x90

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

C++20 - Template Parameter for Lambda  (0) 2023.12.28
C++20 - NonType Template Parameter  (0) 2023.12.28
C++20 - constinit  (2) 2023.12.27
C++20 - consteval  (1) 2023.12.27
C++20 - 지정된 초기화 (Designated Initialization)  (1) 2023.12.17
728x90

constinit은 CompileTime에 상수로 사용하지만, 일반적인 const와는 다르게 변수처럼 사용이 가능하다

특징

1. CompileTime에 상수로 지정된다.
2. constness는 없다. (즉, 값을 변경할 수 있다)
3. global, static, thread_local 변수에서 사용해야된다. (즉, 일반 변수에는 사용할 수 없다)

위의 특징 중에 "값을 변경할 수 있다." 이 부분이 굉장히 특이하다.

 

아래의 코드와 같이 globalA의 값이 상수임에도 변경해서 사용할 수 있다.

constinit int globalA = 10;
constexpr int globalB = 20;

int main()
{
    globalA = 11; // 성공
    globalB = 21; // 이건 에러
    return 0;
}

 

하지만, 이걸 사용할 일이 있을지는 의문이든다. const를 사용한다는건 기본적으로 상수로 보장시키기 위한 것 아닌가...?

728x90
728x90

consteval은 Compile Time은 오래 걸리더라도 미리 계산을 다 해놓겠다고 지정하는 것이라고 생각 하면된다.

 

우리 모두가 알고 있듯이 아래 함수는 RunTime에 계산이 된다 

int Square(int n)
{
    return n * n;
}

하지만 다음과 같이 consteval 키워드를 붙여주면 컴파일 타임에 계산이되어서 상수로 들어가게된다.

consteval int SquareConstEval(int n)
{
    return n * n;
}

 

무슨 말인가하면 프로그램을 디스어셈블리로 확인해보면 좀 더 쉽게 확인할 수 있다.

위에 사진을 보면 Square(10)의 경우 어셈블리로 move, call, move가 RunTime에 직접 계산이 된 것을 확인 할 수 있지만, 아래 SquareConstEval(10)의 경우에는 mov 어셈블리 밖에 없다 왜냐하면 CompileTime에 이미 계산이 된 채로

"int b = 100;" 으로 변경이 된 상태이기 때문이다.

728x90
728x90

이건 다른 언어에서 이미 있었던 기능인데 원하는 변수만 지정해서 초기화하는 기능이다.

다음과 같이 변수 선언과 동시에 중괄호"{}" 사이에 .b 와 같이 "."을 붙여서 원하는 변수만 초기화가 가능하다.

struct MyStruct
{
    int a;
    int b;
    int c;
};

int main()
{
    MyStruct m{.b = 3};
    
    return 0;
}
728x90

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

C++20 - constinit  (2) 2023.12.27
C++20 - consteval  (1) 2023.12.27
C++20 - 삼항 비교 연산자(Three-Way Comparison)  (0) 2023.12.17
C++20 - Coroutine  (1) 2023.12.17
C++20 - Ranges  (0) 2023.12.10
728x90

C++에서 비교 연산자를 만들 때 <, <=, ==, !=, >=, > 등을 모두 만들어야하는 상황이 있었다.

이것을 한번에 만들어주는 거라고 보면된다.

 

쉽게 보면 아래와 같이 기존에 6개의 Operator를 만들어야했지만, 1개만 만들면 자동으로 모두 사용할 수 있게 된다.

struct MyInt
{
    MyInt(int value) : _value(value) { }

    // 기존 문법
    bool operator<(const MyInt& rhs) const { return _value < rhs._value; }
    bool operator<=(const MyInt& rhs) const { return _value <= rhs._value; }
    bool operator>(const MyInt& rhs) const { return _value > rhs._value; }
    bool operator>=(const MyInt& rhs) const { return _value >= rhs._value; }
    bool operator==(const MyInt& rhs) const { return _value == rhs._value; }
    bool operator!=(const MyInt& rhs) const { return _value != rhs._value; }

    // C++ 20 삼항 비교 연산자
    auto operator<=>(const MyInt& rhs) const = default;

    int _value;
};

 

아래와 같이 문자열 비교와 동일한 결과가 나오게 된다.

int main()
{
    int a1 = 100;
    int b1 = 200;

    auto ret = (a1 <=> b1);

    if (ret < 0)
        cout << "a < b" << endl;
    else if (ret == 0)
        cout << "a == b" << endl;
    else if (ret > 0)
        cout << "a > b" << endl;
        
    return 0;
}
728x90

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

C++20 - consteval  (1) 2023.12.27
C++20 - 지정된 초기화 (Designated Initialization)  (1) 2023.12.17
C++20 - Coroutine  (1) 2023.12.17
C++20 - Ranges  (0) 2023.12.10
C++20 - Module  (0) 2023.12.10
728x90

이번 C++ 20에서 가장 기대했던 기능이라서 책도보고 인터넷 검색도 계속하면서 공부를 해본 결과 현재로썬 쉽게 사용하기는 힘들 것 같다...

회사 프로젝트에 적용하기에는 위험 부담이 있다... (디버깅이 너무 힘들 것 같다...)

아마도 코루틴을 이용하는 디자인 패턴이 좀 나오면서 정리가 되면 그때 사용하게 되지 않을까...? 하는 생각이 들 정도이다.

 

유니티를 하면서 코루틴이라는 개념을 처음 접했었는데 개념 자체는 크게 다르진 않은 것 같다.

코루틴의 개념은 이 포스팅에서 잘 설명을 해주고 있다.

(https://m.post.naver.com/viewer/postView.naver?volumeNo=33676443&memberNo=559061)

 

C++20 멀티쓰레드 서버에 코루틴 얹기

[BY MastProgs] C++20 에 추가된 코루틴으로 더 쩔게 코딩할 수 있어졌다< 결론부터 말하기 > C++20의...

m.post.naver.com

 

하지만 사용하기 위해서 준비를 많이 해야되는 부분은 불편해보인다.

 

다른 언어와 달리 C++은 기본적으로 Framework이 존재하지 않는다.

항상 사용자가 만들어서 사용을하든, 다른 라이브러리를 사용하든 어쨋든 간에 별도의 Framework을 생성해야만 한다.

그래서 이러한 준비(약속)가 필요하다.

 

가장 기본적으로 필요한 것은 promise_type이다.

struct promise_type
{
    // 코루틴의 객체를 반환한다.
    CoroutineObject get_return_object() { return {}; }
    
    // 코루틴이 실행 전에 멈춰있어야하는지 확인
    std::suspend_never initial_suspend() const noexcept { return {}; }
    
    // 코루틴이 종료 전에 멈춰있어야하는지 확인
    std::suspend_never final_suspend() const noexcept { return {}; }
    
    // co_return에 의해 호출 (코루틴이 무한 루프로 종료되지 않는다면 불필요)
    void return_void() { }
    
    // co_return val에 의해 호출됨
    void return_value(T value) { *_ptr = value; }
    
    // co_yield에 의해 호출
    std::suspend_always yield_value(const T value) { _value = value; return {}; }
    
    // 예외 발생
    void unhandled_exception() { }
};

 

C++에서의 코루틴 promise_type이라는 객체를 만들어서 커스터마이징을 해야되고, 이것을 이용해서 우리가 아는 코루틴의 개념에 맞게 직접 구현해야한다.

 

구현 내용이 너무 길기 때문에 그냥 다른 포스팅으로 대체한다.

https://openmynotepad.tistory.com/65

 

C++20) Coroutine ( 코루틴 ) - 1

프로그램이 실행될 때 불려지도록 만들어진 프로그램의 중심이 되는 코드들을 Main Routine 이라고 하며, Main Routine 이외에 다른 Routine을 모두 SubRoutine 이라고 한다. 그리고 진입 지점을 여러 개 가

openmynotepad.tistory.com

https://openmynotepad.tistory.com/66

 

C++20) Coroutine ( 코루틴 ) - 2

Coroutine 상태가 할당되면, 해당 할당이 힙에서 발생할 수도 있습니다. ( 힙에 발생해야한다고 생각해야하지만, 컴파일러가 최적화 할 수도 있습니다. ) 만약 힙에서 발생하고, 우리가 만든 promise_t

openmynotepad.tistory.com

https://openmynotepad.tistory.com/67

 

C++20) Coroutine ( 코루틴 ) - 3

co_yield 사용하기 co_yield는 Coroutine의 유용한 키워드이며 일부 값을 반환하지만, 코루틴을 종료시키지 않을 때 사용됩니다. 일반적인 사용 방법은 "특정 유형의 Generator ( 또는 발생기 )"를 생성할

openmynotepad.tistory.com

 

728x90

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

C++20 - 지정된 초기화 (Designated Initialization)  (1) 2023.12.17
C++20 - 삼항 비교 연산자(Three-Way Comparison)  (0) 2023.12.17
C++20 - Ranges  (0) 2023.12.10
C++20 - Module  (0) 2023.12.10
C++20 - Concepts  (0) 2023.12.10
728x90

Ranges는 STL에서 제공되던 iterator의 확장 버전처럼 보인다.

Range : STL 컨테이너를 순회할 수 있는 그룹
View : Range에 대해서 적용할 수 있는 연산

C#의 LINQ 문법과 비슷하다.

키워드 

// std::views::all		
// std::ranges::filter_view / std::views::filter (조건 만족하는거 추출)
// std::ranges::transform_view / std::views::transform (각 요소를 변환)
// std::ranges::take_view / std::views::take (n개 요소를 추출)
// std::ranges::take_while_view / std::views::take_while (조건 만족할 때까지 요소 추출)
// std::ranges::drop_view / std::views::drop (n개 요소를 스킵)
// std::ranges::drop_while_view / std::views::drop_while (조건 만족할 때까지 요소 스킵)
// std::ranges::join_view / std::views::join (view 를 병합)
// std::ranges::split_view / std::views::split (split)
// std::ranges::reverse_view / std::views::reverse (역순서로 순회)
// std::ranges::elements_view / std::views::elements (튜플의 n번째 요소를 대상으로 view 생성)
// std::ranges::keys_view / std::views::keys (pair-like value의 첫번째 요소를 대상으로 view 생성)
// std::ranges::values_view / std::views::values (pair-like value의 두번째 요소를 대상으로 view 생성)

 

벡터의 값들 중에 짝수를 추출해서 2를 곱해준다는 것을 코드로 구현한다면

예전 코드

vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

vector<int> v2;
// 짝수를 추출해서
for (int n : v1)
	if (n % 2 == 0)
		v2.push_back(n);
        
// 2를 곱해준다
for (int& n : v2)
	n = n * 2;

view를 이용한 코드

vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

auto results = v1 | std::views::filter([](int n) { return n % 2 == 0; })
                  | std::views::transform([](int n) { return n * 2; });

 

정렬 방법

vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

std::sort(v1.begin(), v1.end()); // 예전 방식
std::ranges::sort(v1);			 // range를 이용한 방식

 

ref - https://openmynotepad.tistory.com/87

 

C++20) Ranges - 1

1장에서는 Ranges의 기본적인 개요와 view를 다룹니다. 2장에서는 Action을 다룹니다. C++20 에서 Actions가 추가되지 않았습니다. ( 추가가 안된 것은 아니고, namespace 가 추가되지 않음 ) 그에 따라, action

openmynotepad.tistory.com

https://openmynotepad.tistory.com/88

 

C++20) Ranges - 2

views::drop 우리가 문자열 트리밍을 한다고 생각해봅시다. 즉, 어떠한 문자열이 들어오면, 선행/후행 공백이 제거된 새 문자열을 구성하려고 합니다. 예를 들어, "\n\t\r Hello World! \n\n" 를 "Hello World!"

openmynotepad.tistory.com

 

728x90

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

C++20 - 지정된 초기화 (Designated Initialization)  (1) 2023.12.17
C++20 - 삼항 비교 연산자(Three-Way Comparison)  (0) 2023.12.17
C++20 - Coroutine  (1) 2023.12.17
C++20 - Module  (0) 2023.12.10
C++20 - Concepts  (0) 2023.12.10

+ Recent posts