ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C++ 14] 제네릭 프로그래밍 / 추가된 기능과 기억해야 할 내용
    프로그래밍 기초/C++ 2022. 5. 26. 11:00

      제네릭 프로그래밍 

    함수 템플릿

    타입 결정 방법

    = 대부분의 경우 암묵적으로 잘 변환되나 int와 unsigned 같이 모호한 경우 명시적으로 결정해 줘야 한다.


    template<typename TPara>

    TPara max(TPara a, TPara b) { return a > b ? a : b; }

     

    unsigned u1 = 2;

    int i = 3;

    max(u1, i); // 에러 발생!

    max(int(u1), i); // Ok

    max<int>(u1, i); // Ok


     

    자동 리턴 타입

    + 컴파일러에서 리턴 타입도 추론이 가능하게 되었다.


    template<typename T, typename U>

    inline auto max(T a, U b)

    {
        return a > b ? a : b;

    }


     

    네임 스페이스

    네임 스페이스 한정

    = 네임 스페이스로 특정 클래스, 변수 등을 선택해 사용할 수 있다.


    struct same {};

    namespace c1 {

        struct same {};

        namespace c2 {

            struct same {};

            struct csame {

                ::same x; // 전역 same

                c1::same y; // c1의 same

                same z; // c2의 same

            }

        }

    }


     

    = 네임 스페이스를 숨길 수 있다.


    struct same {};

    namespace c1 {

        struct same {};

        namespace c2 {

            struct same {};

            namespace c1{}

            struct csame {

                ::same x; // 전역 same

                c1::same y; // 에러 발생, c1이 c2 내부에 선언되었으나 내부의 c1에는 same이 없다.

                same z; // c2의 same

            }

        }

    }


     

    클래스 템플릿

    템플릿 매개변수

    = 템플릿에 타입 외에 매개변수를 전달할 수 있다.


    template<typename T, int Size>class fsize_vector{    using self = fsize_vector;public:    using value_type = T;

        const static int my_size = Size;

     

        fsize_veoctor(int s = Size) { assert(s == Size); }

        // ...

    private:

        T data[my_size];

    }

     

    fsize_vector<float, 3> v; // 크기가 3인 fsize_vector를 생성한다.


     

    타입 추론과 정의

    표현식의 타입

    = 표현식을 추적하여 적절한 타입을 사용하도록 하는 decltype이 존재한다.


    template<typename Vector1, typename Vector2>

    auto operator+(const Vector1& v1, const Vector2& v2)

        -> vector<decltype(v1[0] + v2[0])>; // v1[0] + v2[0]를 담을 수 있는 타입을 사용한다.


     

    = 긴 표현식에 대해 간편하게 decltype을 사용할 수 있는 decltype(auto)가 존재한다.


    decltype(f(g(x, y, z) + 3 * x)) a = f(g(x, y, z) + 3 * x); // 이러한 표현을

    decltype(auto) b = f(g(x, y, z) + 3 * x); // 이와 같이 바꿀 수 있다.


     

    람다

    값에 의한 캡처

    = 람다 스코프 외부의 변수나 상수를 값으로 참조할 수 있다. [=]으로 모든 변수를 값으로 참조할 수 있다.


    double phi = 2.5;

    auto sin_phi = [phi](double x) { return sin(phi * x); };

     

    // 캡처해온 값은 람다 내부에서 수정이 불가능하며 수정하려면 mutable 키워드를 붙여줘야 한다.

    double phi = 2.5;

    auto sin_phi = [phi](double x) mutable { phi += 0.6; return phi; };


     

    레퍼런스에 의한 캡처

    = 람다 스코프 외부의 변수를 레퍼런스로 참조할 수 있다. [&]로 모든 변수를 레퍼런스로 참조할 수 있다.


    double phi = 2.5;

    auto pxr = [&phi](double x) { phi += x; };

    pxr(1.0); // phi 는 3.5가 된다.


     

    제네릭 람다

    + 람다의 인수 타입을 auto로 사용할 수 있게 되었다.


    auto pxr = [&phi](auto x) { phi +=x; };


     

    댓글

Designed by Tistory.