주제는 이전 에 논의 되었지만 중복 된 것은 아닙니다.
누군가 decltype(a)
와와 의 차이점에 대해 물을 때 decltype((a))
일반적인 대답은 a
변수 (a)
입니다. 이 답변이 만족스럽지 않습니다.
먼저 a
표현도 있습니다. 기본 표현식 의 옵션 에는 다음이 포함됩니다.
- ( 표현 )
- 아이디 표현
더 중요한 것은 decltype에 대한 문구는 괄호를 매우 명확하게 고려한다는 것입니다 .
For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1) if e is an unparenthesized id-expression naming a structured binding, ...
(1.2) otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3) otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, ...
(1.4) otherwise, ...
그래서 질문은 남아 있습니다. 괄호가 다르게 취급되는 이유 는 무엇 입니까? 기술 문서 나위원회 토론에 익숙한 사람이 있습니까? 괄호에 대한 명시적인 고려는 이것이 감독이 아니라고 생각하게하므로 누락 된 기술적 이유가 있어야합니다.
답변
감독이 아닙니다. 그것은에 있다는 흥미로운 Decltype 자동차 (개정 4) (N1705 = 04-0145) 성명이있다 :
decltype 규칙
decltype((e)) == decltype(e)
에 EWG에서 제안한대로 명시 적으로 명시 되어 있습니다.
그러나 Decltype (개정 6) : 제안 된 문구 (N2115 = 06-018) 에서 변경된 사항 중 하나는 다음과 같습니다.
decltype 내부의 괄호로 묶인 표현식은로 간주되지 않습니다
id-expression
.
문구에는 이론적 근거가 없지만 약간 다른 구문을 사용하여 일종의 decltype을 확장한다고 가정합니다. 즉, 이러한 경우를 구별하기위한 것입니다.
그 사용법은 C ++ draft9.2.8.4에 나와 있습니다.
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
정말 흥미로운 점은 return
명령문 과 작동하는 방식입니다 .
decltype(auto) f()
{
int i{ 0 };
return (i);
}
내 Visual Studio 2019는 중복 괄호를 제거하도록 제안하지만 실제로 는 로컬 변수에 대한 참조를 반환 한 후 decltype((i))
반환 값을 변경 int&
하여 UB로 만드는 변경 사항으로 바뀝니다 .
답변
괄호가 다르게 취급되는 이유는 무엇입니까?
괄호는 다르게 취급되지 않습니다. 다르게 취급되는 것은 괄호로 묶이지 않은 id 표현입니다.
괄호가 있으면 모든 표현식에 대한 규칙이 적용됩니다. 유형 및 값 범주는의 유형으로 추출되고 체계화됩니다 decltype
.
유용한 코드를보다 쉽게 작성할 수 있도록 특별 조항이 있습니다. decltype
(멤버) 변수의 이름에 적용 할 때 일반적으로 표현식으로 취급 될 때 변수의 속성을 나타내는 일부 유형을 원하지 않습니다. 대신 우리는 변수를 얻기 위해 많은 유형 특성을 적용하지 않고도 변수가 선언 된 유형 만 원합니다. 그것이 바로 decltype
우리에게 지정된 것입니다.
만약우리가 표현식으로서 변수의 속성에 관심이 , 여분의 괄호를 사용하여 변수를 쉽게 얻을 수 있습니다.
답변
C ++ 11 이전의 언어에는 두 가지 종류의 정보 를 얻기위한 도구가 필요 합니다 .
- 표현식의 유형
- 선언 된 변수의 유형
이 정보의 특성으로 인해 기능을 언어로 추가해야했습니다 (라이브러리에서는 수행 할 수 없음). 이는 새로운 키워드를 의미합니다. 표준은이를 위해 두 개의 새로운 키워드를 도입했을 수 있습니다. 예를 들어 exprtype
표현식의 유형 decltype
을 가져 오고 변수의 선언 유형을 가져옵니다. 그것은 분명하고 행복한 선택이었습니다.
그러나 표준위원회는 기존 코드의 손상을 최소화하기 위해 언어에 새로운 키워드 를 도입하지 않도록 항상 최선을 다했습니다 . 이전 버전과의 호환성은 언어의 핵심 철학입니다.
C ++ 11에서는 두 가지 다른 키워드로 사용되는 키워드가 하나만 decltype
있습니다. 두 가지 용도를 구별하는 방식은 decltype(id-expression)
다르게 취급하는 것입니다. 위원회의 의식적인 결정, (작은) 타협.