C ++ 선언과 괄호-왜?


32

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

누군가 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, ...

그래서 질문은 남아 있습니다. 괄호가 다르게 취급되는 이유 는 무엇 입니까? 기술 문서 나위원회 토론에 익숙한 사람이 있습니까? 괄호에 대한 명시적인 고려는 이것이 감독이 아니라고 생각하게하므로 누락 된 기술적 이유가 있어야합니다.


2
"일반적인 대답은-a는 변수이고, (a)는 표현식입니다"- " 의미는 (a)표현 a이며, 표현 과 변수"입니다.
— HolyBlackCat

답변:


18

감독이 아닙니다. 그것은에 있다는 흥미로운 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로 만드는 변경 사항으로 바뀝니다 .


원점을 정확히 찾아 주셔서 감사합니다! decltype을 다르게 지정할 수 있었을뿐만 아니라 처음에 밝혀졌습니다. 목사-6 문서는 명시 적으로 재미 괄호 동작을 추가하지만 우리가 지금 얻을 것 같은 .. 근거 :( 내가 대답에 가까운이의 추측을 건너 뜁니다.
— Ofek Shilon

그러나 아무도 두 가지 다른 기능을 위해 두 개의 별개의 키워드를 만들어 바보 같은 문제를 해결하도록 제안하지 않았습니까? 위원회의 가장 큰 실수 중 하나입니다 (역사적으로 많은 강제 오류가 발생했습니다).
— curiousguy

13

괄호가 다르게 취급되는 이유는 무엇입니까?

괄호는 다르게 취급되지 않습니다. 다르게 취급되는 것은 괄호로 묶이지 않은 id 표현입니다.

괄호가 있으면 모든 표현식에 대한 규칙이 적용됩니다. 유형 및 값 범주는의 유형으로 추출되고 체계화됩니다 decltype.

유용한 코드를보다 쉽게 ​​작성할 수 있도록 특별 조항이 있습니다. decltype(멤버) 변수의 이름에 적용 할 때 일반적으로 표현식으로 취급 될 때 변수의 속성을 나타내는 일부 유형을 원하지 않습니다. 대신 우리는 변수를 얻기 위해 많은 유형 특성을 적용하지 않고도 변수가 선언 된 유형 만 원합니다. 그것이 바로 decltype우리에게 지정된 것입니다.

만약우리가 표현식으로서 변수의 속성에 관심이 , 여분의 괄호를 사용하여 변수를 쉽게 얻을 수 있습니다.


그래서에 대한 int회원 i의 a, decltype(a.i)되는 int동안 decltype((a.i))이다 int&(가정 a입니다하지 const)? 표현 a.i이 할당 가능 하기 때문에 ?
— n314159

1
@ n314159-그것의 요지입니다. 표현식 a.i은 상수가 아닌 lvalue이므로에 대한 상수가 아닌 lvalue 참조 유형을 얻습니다 (a.i).
— StoryTeller-Unslander Monica

'모든 표현식에 대한 일반 규칙'이 유형이 참조임을 나타내는 이유는 무엇입니까? '표현식 변수의 속성'에 참조 속성이 포함되는 이유는 무엇입니까? 자연스럽게 불이행입니까?
— Ofek Shilon

1
@OfekShilon-유형이 참조가 아닙니다. 식의 유형은 참조로 분석되지 않습니다 . 그러나 dectlype는 형식으로 만 확인할 수 있으며 표현식의 형식뿐만 아니라 값 범주도 알려줍니다. 값 범주는 참조 유형별 로 체계화 되어 있습니다. lvalues는 &xvalues는 &&prvalues는 참조 유형이 아닙니다.
— StoryTeller-Unslander Monica

@StoryTeller 정확하게 표현의 유형과 표현이 아닌 유형 사이에는 '자연스러운'차이가 없습니다. 그것은 구별을 인공적으로 만듭니다.
— Ofek Shilon

1

C ++ 11 이전의 언어에는 두 가지 종류의 정보 를 얻기위한 도구가 필요 합니다 .

  • 표현식의 유형
  • 선언 된 변수의 유형

이 정보의 특성으로 인해 기능을 언어로 추가해야했습니다 (라이브러리에서는 수행 할 수 없음). 이는 새로운 키워드를 의미합니다. 표준은이를 위해 두 개의 새로운 키워드를 도입했을 수 있습니다. 예를 들어 exprtype표현식의 유형 decltype을 가져 오고 변수의 선언 유형을 가져옵니다. 그것은 분명하고 행복한 선택이었습니다.

그러나 표준위원회는 기존 코드의 손상을 최소화하기 위해 언어에 새로운 키워드 를 도입하지 않도록 항상 최선을 다했습니다 . 이전 버전과의 호환성은 언어의 핵심 철학입니다.

C ++ 11에서는 두 가지 다른 키워드로 사용되는 키워드가 하나만 decltype있습니다. 두 가지 용도를 구별하는 방식은 decltype(id-expression)다르게 취급하는 것입니다. 위원회의 의식적인 결정, (작은) 타협.


나는 이것을 cpp 강연에서 듣는 것을 기억합니다. 그러나 소스를 찾을 희망은 없습니다. 누군가 그것을 찾으면 좋을 것입니다.
— bolov

1
C ++은 역사적으로 많은 새로운 키워드를 추가했습니다. 합리적인 것은 정말 터무니 없다.
— curiousguy

@curiousguy는 도입 된 모든 키워드가 기존 사용자 기호와 충돌하므로위원회는 새로운 예약 키워드를 언어에 추가 할 때 많은 비중을 두게됩니다. 터무니없는 IMO가 아닙니다.
— bolov

사실 export이 아닙니다 : 소개되었습니다. 당신이 할 수 있다면 export, 당신은 같은 물건을 할 수 있습니다 (이전에 모든 템플릿은 기본 "수출"에 의해 있었다) decltype와 constexpr. 분명히 register다른 언어로 추가하는 것은 문제가 될 것입니다.
— curiousguy

@bolov 감사합니다! (1)이 추측이나 지식인가? 추가 키워드를 피하는 것이 동기가 된 토론에 대해 알고 있습니까? (2) id- 표현식이 "표현식"으로 사용될 경우 실제로 다르게 취급 될 필요가있는 예를들 수 있습니까? (이것은 무엇을 의미합니까?)
— Ofek Shilon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.