17. auto / decltype / decltype(auto) 추론 규칙과 decltype((expr)) 괄호 함정

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// 주제: auto / decltype / decltype(auto) 의 타입 추론 규칙과 decltype((expr)) 의 괄호 함정.
//
// auto 는 (템플릿 인자 추론처럼) 참조와 cv 한정자를 떨어뜨리고 값으로 추론한다.
// decltype(e) 는 e 의 "선언된 타입"을 그대로 주되, e 가 괄호로 싸인 lvalue 표현식이면
// 참조 타입이 된다. decltype(auto) 는 초기화식의 decltype 규칙으로 추론한다.
//
// 과제:
//   1) 이 프로그램의 정확한 표준출력을 예측하라(특히 w.v, a, 세 is_ref 값, global).
//   2) a, b, c 의 타입이 각각 무엇으로 추론되는지(int vs int&) 와 그 이유를 설명하라.
//   3) decltype(w.v) 와 decltype((w.v)) 가 왜 다른지(괄호 규칙)를 설명하라.
//   4) decltype(auto) d = getRef(); 가 d 를 어떤 타입으로 만드는지, 그리고 만약
//      auto d = getRef(); 였다면 무엇이 달라지는지 설명하라.

#include <cstdio>
#include <type_traits>

struct Widget { int v = 10; };

int  global = 42;
int& getRef() { return global; }

int main() {
    Widget w;
    int& r = w.v;

    auto a = r;               // (1) 어떤 타입?
    a = 99;

    decltype(w.v)   b = w.v;  // (2) 어떤 타입?
    decltype((w.v)) c = w.v;  // (3) 어떤 타입?
    c = 77;

    std::printf("w.v=%d a=%d b=%d\n", w.v, a, b);
    std::printf("is_ref a: %d\n", std::is_reference<decltype(a)>::value);
    std::printf("is_ref b: %d\n", std::is_reference<decltype(b)>::value);
    std::printf("is_ref c: %d\n", std::is_reference<decltype(c)>::value);

    decltype(auto) d = getRef();  // (4) 어떤 타입?
    d = 1000;
    std::printf("global=%d\n", global);
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.