Declarations
선언(Declarations) 은 이름이 C++ 프로그램에 도입(또는 재도입)되는 방법입니다. 모든 선언이 실제로 무언가를 선언하는 것은 아니며, 각 종류의 엔터티는 서로 다르게 선언됩니다. 정의(Definitions) 는 이름으로 식별되는 엔터티를 사용하기에 충분한 선언입니다.
선언은 다음 중 하나입니다:
|
(C++11부터) |
-
빈 선언 (
;) - decl-specifier-seq 없이 이루어진 함수 선언:
attr
(선택 사항)
declarator
;
|
|||||||||
| attr | - | (since C++11) 임의 개수의 attributes 시퀀스 |
| declarator | - | 함수 선언자 |
- 이 선언은 생성자, 소멸자, 또는 사용자 정의 타입 conversion function 을 선언해야 합니다. 이것은 template declaration , explicit specialization , 또는 explicit instantiation의 일부로만 사용될 수 있습니다.
- block-declaration (블록 내부에 나타날 수 있는 선언으로, 이는 다음 중 하나일 수 있음):
| (C++11부터) |
| (C++20부터) | |
| (C++11부터) |
-
- 단순 선언
내용간단한 선언간단한 선언은 하나 또는 여러 식별자(일반적으로 변수)를 도입하고 생성하며 선택적으로 초기화하는 문장입니다.
1) 초기화자가 있는 선언자.
2) 초기화자가 없는 선언자.
지정자선언 지정자 ( decl-specifier-seq )는 다음의 공백으로 구분된 지정자들이 임의의 순서로 나열된 시퀀스입니다:
속성 은 decl-specifier-seq 에 나타날 수 있으며, 이 경우 앞에 나온 지정자들에 의해 결정된 타입에 적용됩니다. decl-specifier-seq 내에서의 모든 지정자 반복, 예를 들어 const static const 또는 virtual inline virtual 는 오류입니다 , 단 long 이 두 번 나타나는 것은 허용됨 (C++11부터) . 선언자init-declarator-list 내의 각 init-declarator 는 동일한 지정자를 가진 독립 선언문처럼 처리됩니다: S D1, D2, D3 ; 는 다음과 같이 처리됩니다: S D1 ; S D2 ; S D3 ; . 각 선언자는 정확히 하나의 객체, 참조, 함수, 또는 (typedef 선언의 경우) 타입 별칭을 도입하며, 그 타입은 decl-specifier-seq 에 의해 제공되고 선언자 내에서 & (참조)나 [ ] (배열) 또는 ( ) (함수 반환)과 같은 연산자들에 의해 선택적으로 수정될 수 있습니다. 이러한 연산자들은 아래에 보여지는 것처럼 재귀적으로 적용될 수 있습니다. 선언자는 다음 중 하나입니다:
1)
선언된
name
.
5)
멤버 포인터 선언
: 선언문
S C
::
*
D
;
는
D
를
C
의 멤버 포인터로 선언하며, 그 타입은
decl-specifier-seq
S
에 의해 결정됩니다.
nested-name-specifier
는
이름과 범위 확인 연산자
::
의 시퀀스입니다
6)
Lvalue reference declarator
: 선언문
S
&
D
;
는
D
를
decl-specifier-seq
S
에 의해 결정된 타입에 대한 lvalue reference로 선언합니다.
7)
Rvalue reference declarator
: 선언문
S
&&
D
;
는
D
를
decl-specifier-seq
S
에 의해 결정된 타입에 대한 rvalue 참조로 선언합니다.
9)
함수 선언자
.
noptr-declarator
모든 유효한 선언자이지만, *, &, 또는 &&로 시작하는 경우 괄호로 둘러싸여야 합니다.
선택적 후행 반환 타입으로 끝날 수 있습니다.
(C++11부터)
10)
괄호로 묶인 선언자.
cv 는 const 및 volatile 한정자들의 시퀀스이며, 각 한정자는 시퀀스 내에서 최대 한 번만 나타날 수 있습니다.
참고 사항블록 내부에 block-declaration 이 나타날 때, 선언에 의해 도입된 식별자가 이전에 외부 블록에서 선언된 경우 외부 선언은 블록의 나머지 부분에 대해 숨겨집니다 . 자동 저장 기간을 가진 변수를 선언하는 선언문이 실행될 때 해당 변수가 초기화됩니다. 블록 내에서 선언된 모든 자동 변수는 블록을 벗어날 때 (블록이 어떻게 종료되든: exception , goto , 또는 블록 끝에 도달함) 초기화 순서의 역순으로 소멸됩니다. 예제참고: 이 예제는 언어 문법 측면에서 몇 가지 복잡한 선언이 어떻게 파싱되는지 보여줍니다. 다른 널리 사용되는 기억법으로는: the spiral rule , inside-out 읽기, 그리고 declaration mirrors use 가 있습니다. 또한 https://cdecl.org 에 자동화된 파서도 있습니다.
이 코드 실행
#include <type_traits> struct S { int member; // decl-specifier-seq is "int" // declarator is "member" } obj, *pObj(&obj); // decl-specifier-seq is "struct S { int member; }" // declarator "obj" declares an object of type S // declarator "*pObj" declares a pointer to S, // and initializer "(&obj)" initializes it int i = 1, *p = nullptr, f(), (*pf)(double); // decl-specifier-seq is "int" // declarator "i" declares a variable of type int, // and initializer "= 1" initializes it // declarator "*p" declares a variable of type int*, // and initializer "= nullptr" initializes it // declarator "f()" declares (but doesn't define) // a function taking no arguments and returning int // declarator "(*pf)(double)" declares a pointer to function // taking double and returning int int (*(*var1)(double))[3] = nullptr; // decl-specifier-seq is "int" // declarator is "(*(*var1)(double))[3]" // initializer is "= nullptr" // 1. declarator "(*(*var1)(double))[3]" is an array declarator: // Type declared is: "(*(*var1)(double))" array of 3 elements // 2. declarator "(*(*var1)(double))" is a pointer declarator: // Type declared is: "(*var1)(double)" pointer to array of 3 elements // 3. declarator "(*var1)(double)" is a function declarator: // Type declared is: "(*var1)" function taking "(double)", // returning pointer to array of 3 elements. // 4. declarator "(*var1)" is a pointer declarator: // Type declared is: "var1" pointer to function taking "(double)", // returning pointer to array of 3 elements. // 5. declarator "var1" is an identifier. // This declaration declares the object var1 of type "pointer to function // taking double and returning pointer to array of 3 elements of type int" // The initializer "= nullptr" provides the initial value of this pointer. // C++11 alternative syntax: auto (*var2)(double) -> int (*)[3] = nullptr; // decl-specifier-seq is "auto" // declarator is "(*var2)(double) -> int (*)[3]" // initializer is "= nullptr" // 1. declarator "(*var2)(double) -> int (*)[3]" is a function declarator: // Type declared is: "(*var2)" function taking "(double)", returning "int (*)[3]" // ... int main() { static_assert(std::is_same_v<decltype(var1), decltype(var2)>); } 결함 보고서다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
참고 항목
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||