ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 항목 3. decltype의 작동 방식을 숙지하라.
    프로그래밍/Modern Effective c++ 2016. 3. 28. 15:14
    decltype는 주어진 이름이나 표현식의 형식을 알려준다.
    대부분 다음과같이 예측한 대로 형식을 말해준다.

    const int i = 0;                     // decltype(i) : const int
    bool f(const Widget& w);      // decltype(w) : const Widget&
                                              // decltype(f) : bool(const Widget&)

    struct Point {                       // decltype(Point::x) : int
         int x, y;                          // decltype(Point::y) : int
    };

    Widget w;                           // decltype(w) : Widget

    if(f(w));                              // decltype(f(w)) : bool

    template<typename T>
    class vector {
    public:
         ...
         T& operator[] (std::size_t index);
    };

    vector<int> v;                     // decltype(v)는 vector<int>
    ...
    if(v[0] == 0) ...                   // decltype(v[0])은 int&



    c++11에서 decltype은 다음과같이 함수의 반환 형식이 그 매개변수 형식들에 의존하는 함수 템플릿을 선언할 때 주로 사용한다.

    template<typename Container, typename Index>
    auto authAndAccess(Container& c, Index i)
         ->decltype(c[i])
    {
         authenticateUser();
         return c[i];
    }

    형식 T를 담은 컨테이너들에 대한 operator[]연산은 일반적으로 T&을 돌려주지만 std::vector<bool>은
    완전히 새로운 객체(T)  를 돌려주기 때문에 이렇게 써주는 것이 좋다. --> 그런데 그건 그냥 c[i]를 반환해도 T를 돌려주지 않나요..

    c++11에서는 위와같이 함수 이름 앞에 auto를 써주는 것은 형식 연역과는 아무 상관이 없다. 
    단지 후행반환 형식, 즉 이자리가 아니라 매개변수 목록 다음에 반환 형식을 선언 하겠다는 것을 나타내는 것이다.
    이 방식의 장점은 매개변수들을 이용해서 반환형식을 지정할 수 있다 것이다.
    하지만 c++14에서는 반환형식 연역을 허용한다.

    c++11은 람다함수가 한문장으로 이루어져있다면 반환형식의 연역을 허용하고,
    c++14에서는 모든 람다와 모든 함수의 반환형식 연역을 허용한다.

    이때 c++14에서 다음과 같은 상황이 발생한다.

    template<typename Container, typename Index>
    auto authAndAccess(container& c, Index i)
    {
         authAndAccess(Container& c, Index i)
         return c[i];
    }

    위와같이 선언 했을 때, c[i]의 형식은 &c[i] 이지만, auto의 형식 연역 방식에 따라 c[i]를 돌려주게 된다.
    따라서 이를 막기 위해 다음과 같이 선언 한다.

    template<typename Container, typename Index>
    decltype(auto) authAndAccess(container& c, Index i)
    {
         authAndAccess(Container& c, Index i)
         return c[i];
    }

    이 외에도 auto에 의해 &가 생략되는 모든 곳에 &가 생략되지 않게 하기 위해 쓸 수 있다.

    이 다음 부분은 나중에 이해할 수 있을 때 다시 보고 정리하겠다..


Designed by Tistory.