중괄호가있는 참조 유형의 변수에 대한 decltype
다음 코드를 고려하십시오 .
#include <type_traits>
int main() {
const int& p = 42;
auto v1 = decltype(p){};
static_assert(std::is_same_v<decltype(v1), int>);
decltype(p) v2{};
static_assert(std::is_same_v<decltype(v2), const int&>);
// auto v3 = X(const int&)X {};
}
유형은 v1
로 추론됩니다 int
. 같은 시간 유형에서 v2
예상대로로 추론된다 const int&
. 에 대한 첫 번째 단계는 v1
유형 별칭을 하나 더 추가 한 using T = decltype(p);
다음 auto v4 = T{};
. 이 표현식 ( decltype(p){}
또는 T{}
)은 컴파일러에서 어떻게 처리됩니까? 그 {}
부분이 인스턴스화를위한 것이라는 것을 알고 있지만 결과 유형이 v1
참조 유형이 아닌 이유는 무엇입니까?
또 다른 질문 : (대신 ) 명시 적으로 언급 된 유형 v3
을 v1
사용 하는 것과 동일한 유형의 변수 를 선언하는 방법이 있습니까?const int&
decltype(p)
표준에 대한 모든 링크를 주시면 감사하겠습니다.
답변
(비정 투표자에게 : Scott Meyers를 인용하는 것이 표준을 인용하는 것과 같지 않다고 생각하여 반대표를 던졌다면, 오 글쎄요 ...)
Effective Modern C ++ 에서 읽을 수있는 것처럼 ( 해당 링크에서 검색하여 도달 할 수 있는 정오표 의 일부가 추가되어 Case 2:
다음 읽기가 더 간단 해지지 만 질문에 필수적인 것은 아닙니다) :
경우
ParamType
비 참조 경우 [...]expr
의 타입이 레퍼런스 인, 기준 부분을 무시한다. [...]expr
이const
이면 그도 마찬가지입니다. 인 경우volatile
무시하십시오.
param
선언 지정자는 어디 입니까? 귀하의 경우에는 단지 auto
, 즉 비 참조입니다.
즉, v1
일반 auto
(아님 auto&
), 즉 복사 를 통해 생성 하므로 참조인지 아닌 엔티티로 초기화하는지 여부 const
( volatile
또는 포함하지 않음, fwiw) 로 초기화하는지 여부는 중요하지 않습니다 . 당신이 그것을 복사하고 있기 때문입니다.
더 간단한 경우를 생각해보세요.
int i = 3;
int& p = i;
auto v1 = p;
멀리로 v1
우려, 정말이 하나 initalized 여부를 중요 (아니다 i
) 또는 다른 ( p
하는) 이름이 같은 그 개체가 가지고있는 어떤 값의 사본을 얻을 수 있기 때문에, 실체가 알려져있다.
auto
유형 추론은 템플릿 유형 추론과 동일하게 작동하며 (이 경우에는 관련이없는 중괄호 이니셜 라이저를 처리하는 방식의 차이를 제외하고) 둘 다 Scott Meyers의 Effective Modern C ++를 참조 할 수 있습니다 .