C ++에서 변수를 선언 할 때 변수 이름을 괄호로 묶을 수있는 이유는 무엇입니까?


84

예를 들어 다음과 같은 선언이 있습니다.

int (x) = 0;

또는 그것도 :

int (((x))) = 0;

내 코드에서 다음과 유사한 조각이 발생했기 때문에 이것을 우연히 발견했습니다.

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}

분명히 나는 C소멸자에서 유용한 일을 할 객체 를 만들고 싶었습니다 . 그러나 컴파일러는 유형 C (y);이있는 변수의 선언으로 취급 하므로 재정의에 대한 오류를 인쇄합니다 . 재미있는 것은 내가로 작성하는 경우이다 또는 무언가로 같이 가 의도 한대로 컴파일. 가장 현대적인 해결 방법은 물론 생성자 호출 에 사용하는 것 입니다.yCyC (y).f ()C (static_cast<B*> (y)){}

그래서 내가 그 후에 알아 냈 듯이 변수를 같은 int (x) = 0;또는 심지어 선언하는 것이 가능 int (((x))) = 0;하지만 실제로 이와 같은 선언을 사용하는 사람을 본 적이 없습니다. 그래서 저는 관심이 있습니다. 현재로서는 악명 높은 "가장 성가신 구문 분석"과 유사한 경우 만 생성하고 유용한 것은 추가하지 않기 때문에 그러한 가능성의 목적은 무엇입니까?


가능성의 "목적"은 아마도 파서를 단순화하는 것입니다.
molbdnilo


1
@GSerg 내 질문의 텍스트가 링크 된 질문의 두 번째 답변에서 질문에 어떻게 대답하는지 웃기게되는데, 이러한 선언을 허용하면 예상치 못한 결과가 발생하는 예를 제공하기 때문에 :)
Predelnik


이 함정에 들어갔다 : 뮤텍스가 주석 처리 된 것을 몰랐고 실수로 잘못된 괄호 선언을 작성했습니다. // std :: mutex std :: unique_lock <std :: mutex> (m_mutex);
Laurijssen 봉사

답변:


80

그룹화.

특정 예로서, 다음과 같은 함수 유형의 변수를 선언 할 수 있습니다.

int f(int);

자, 그런 것에 대한 포인터를 어떻게 선언 하시겠습니까?

int *f(int);

아니, 작동하지 않습니다! 이것은를 반환하는 함수로 해석됩니다 int*. 올바른 방법으로 구문 분석하려면 괄호를 추가해야합니다.

int (*f)(int);

배열도 마찬가지입니다.

int *x[5];   // array of five int*
int (*x)[5]; // pointer to array of five int

13
그리고 답을 완성하기 위해 : 질문자가 요청하는 특정 케이스를 허용하지 않는 것은 추가 특수 케이스 규칙이 필요합니다. ()유형의 작업 방식에 대한 현재 정의 는 유형 전체에서 동일합니다.
Joseph Mansfield

따라서 특수한 경우는 가장 복잡한 구문 분석에 적용됩니다. 이것은 생성자 인수로 변수를 초기화하는 구문이 나중에 추가 되었기 때문입니다 (서둘러 요?).
AnArrayOfFunctions 2015-04-16

1
@FISOCPP 음. . 예. C ++는 C 다음에 왔습니다.. .
iheanyi

이 대답은 C ++뿐만 아니라 C에도 똑같이 적용됩니까?
kdbanman 2015

" 함수 유형의 변수 "뭐? !!
curiousguy

17

구문상의 관점에서 볼 때 선언은 항상 다음과 같이 보이기 때문에 일반적으로 이러한 선언에 괄호를 사용할 수 있습니다.

<front type> <specification>;

예를 들어, 다음 선언에서 :

int* p[2];

"전면 유형"은 int(아님 int*)이고 "사양"은 * p[2]입니다.

규칙은 "사양"부분에서 필요한만큼 괄호를 사용할 수 있다는 것입니다. 괄호는 때때로 명확하게하기 위해 불가피하기 때문입니다. 예를 들면 :

int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints

배열에 대한 포인터는 드물지만 함수에 대한 포인터와 동일한 상황입니다.

int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int

이것은 귀하의 질문에 대한 직접적인 대답입니다. 질문이과 같은 진술에 관한 C(y)것이라면 :

  • 전체 표현식을 괄호로 묶으 (C(y))면 원하는 것을 얻을 수 있습니다.
  • 이 명령문은이 지침이 종료 된 후 더 이상 지속되지 않는 임시 객체를 만드는 것 외에는 수행하지 않습니다.

1
내가 언급했듯이, 처음에는 소멸자에서 무언가를하고 있었는데, 일부 매개 변수를 설정하고 소멸자에서 모든 작업을 수행하기위한 "연결"기능이 몇 가지있을 때 꽤 표준적인 일이라고 생각합니다. 한 가지 더 해결 방법에 감사드립니다 {}. 결국 쓰기 가 가장 유효한 것 같습니다.
Predelnik 2015

4
자신의 문법을 만드는 것을 피하고 표준에 제공된 문법을 사용하십시오. <front-type> <specification>오해의 소지가 있고 잘못되었습니다. 문법은<declaration-specifier> <declarator>
Steve Cox

당신 말이 맞아요-나는 표준을 조사하지 않았고, 단지 내 머리에서 규칙을 반복했습니다. 실제로 C ++ 11에서의 역할은 키워드 <declaration-specifier>로도 수행 될 수 있으므로 auto항상 유형이 아닙니다.
Ethouris

@Pravasi Meet : 내 게시물의 일부를 편집하고 주어진 구문 스키마에서 이름을 변경 한 경우 그에 따라 아래 3 줄의 이름도 변경하십시오. 그렇지 않으면 여전히 "전면 유형"과 "사양"이라는 오래된 이름이 있으므로 게시물이 의미가 없습니다.
Ethouris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.