C ++ 선언과 괄호-왜? 의 옵션 에는 다음이 포함됩니다. ( 표현

주제는 이전논의 되었지만 중복 된 것은 아닙니다.

누군가 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)다르게 취급하는 것입니다. 위원회의 의식적인 결정, (작은) 타협.


답변