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회원 ia, 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, 당신은 같은 물건을 할 수 있습니다 (이전에 모든 템플릿은 기본 "수출"에 의해 있었다) decltypeconstexpr. 분명히 register다른 언어로 추가하는 것은 문제가 될 것입니다.
curiousguy

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