Namespaces
Variants

Declarations

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

선언(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부터)
  • 단순 선언

목차

단순 선언

단순 선언은 하나 이상의 식별자(일반적으로 변수)를 도입하고 생성하며, 선택적으로 초기화하는 문장입니다.

decl-specifier-seq init-declarator-list  (선택적) ; (1)
attr decl-specifier-seq init-declarator-list ; (2) (C++11 이후)
decl-specifier-seq - 지정자 의 시퀀스
init-declarator-list - init-declarator 들의 쉼표로 구분된 목록 (아래 참조)
attr - 임의 개수의 속성 시퀀스


init-declarator-list 는 명명된 클래스 또는 명명된 열거형을 선언할 때만 생략할 수 있습니다.

구조화된 바인딩 선언 또한 단순 선언입니다.

(C++17부터)


init-declarator 의 구문은 다음과 같이 정의됩니다:

declarator initializer (1)
declarator requires-clause  (선택적) contract-specs  (선택적) (2)
1) 초기화자를 갖는 선언자.
2) 초기화자가 없는 선언자.
declarator - a declarator
initializer - an initializer
requires-clause - (since C++20) a requires clause
contract-specs - (since C++26) a list of function contract specifiers


requires-clause declarator 템플릿 함수 를 선언하는 경우에만 나타날 수 있습니다.

(C++20부터)

contract-specs declarator 가 함수 또는 함수 템플릿을 선언하는 경우에만 나타날 수 있습니다.

(C++26부터)

지정자

선언 지정자 ( decl-specifier-seq )는 다음의 공백으로 구분된 지정자들이 임의의 순서로 나열된 시퀀스입니다:

  • inline 지정자는 변수 선언에서도 허용됩니다.
(C++17부터)
  • friend 지정자는 클래스 및 함수 선언에서 허용됩니다.
  • constexpr 지정자는 변수 정의, 함수 및 함수 템플릿 선언, 리터럴 타입의 정적 데이터 멤버 선언에서만 허용됩니다.
(C++11부터)
  • consteval 지정자는 함수 및 함수 템플릿 선언에서만 허용됩니다.
  • constinit 지정자는 정적 또는 스레드 저장 기간을 가진 변수의 선언에서만 허용됩니다. constexpr , consteval , constinit 지정자 중 최대 하나만 decl-specifier-seq 에 나타날 수 있습니다.
(C++20부터)
  • 저장 클래스 지정자 ( register , (C++17까지) static , thread_local , (C++11부터) extern , mutable ). 오직 하나의 저장 클래스 지정자만 허용됨 , 단 thread_local extern 또는 static 과 함께 나타날 수 있음 (C++11부터) .
  • 타입 지정자 ( type-specifier-seq ), 타입을 명명하는 지정자들의 시퀀스. 선언에 의해 도입된 모든 엔티티의 타입은 이 타입이며, 선택적으로 선언자에 의해 수정될 수 있음(아래 참조). 이 지정자 시퀀스는 type-id 에서도 사용됨. 다음 지정자들만이 type-specifier-seq 의 일부이며, 임의의 순서로 나타날 수 있음:
(C++11 이후)
(C++26 이후)
(C++17부터)
decl-specifier-seq에서는 하나의 타입 지정자만 허용되며, 다음 예외가 적용됩니다:
  • const 는 자기 자신을 제외한 모든 타입 지정자와 결합할 수 있습니다.
  • volatile 는 자기 자신을 제외한 모든 타입 지정자와 결합할 수 있습니다.
  • signed 또는 unsigned char , long , short , 또는 int 와 결합할 수 있습니다.
  • short 또는 long int 와 결합할 수 있습니다.
  • long double 와 결합할 수 있습니다.
  • long long 과 결합될 수 있습니다.
(C++11부터)

속성 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 에 의해 제공되고 선언자 내에서 & (참조)나 [ ] (배열) 또는 ( ) (함수 반환)과 같은 연산자들에 의해 선택적으로 수정될 수 있습니다. 이러한 연산자들은 아래에 보여지는 것처럼 재귀적으로 적용될 수 있습니다.

선언자는 다음 중 하나입니다:

unqualified-id attr  (선택 사항) (1)
qualified-id attr  (선택 사항) (2)
... identifier attr  (선택 사항) (3) (C++11 이후)
* attr  (선택 사항) cv  (선택 사항) declarator (4)
nested-name-specifier * attr  (선택 사항) cv  (선택 사항) declarator (5)
& attr  (선택 사항) declarator (6)
&& attr  (선택 사항) declarator (7) (C++11 이후)
noptr-declarator [ constant-expression  (선택 사항) ] attr  (선택 사항) (8)
noptr-declarator ( parameter-list ) cv  (선택 사항) ref   (선택 사항) except  (선택 사항) attr  (선택 사항) (9)
( declarator ) (10)
1) 선언된 name .
2) 한정된 식별자( qualified-id )를 사용하는 선언자는 이전에 선언된 네임스페이스 멤버 또는 클래스 멤버 를 정의하거나 재선언합니다.
3) Parameter pack , 매개변수 선언 에서만 나타납니다.
4) 포인터 선언자 : 선언문 S * D ; D decl-specifier-seq S 에 의해 결정된 타입에 대한 포인터로 선언합니다.
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 참조로 선언합니다.
8) 배열 선언자 . noptr-declarator 유효한 선언자이지만, *, &, 또는 &&로 시작하는 경우 괄호로 둘러싸여야 합니다.
9) 함수 선언자 . noptr-declarator 모든 유효한 선언자이지만, *, &, 또는 &&로 시작하는 경우 괄호로 둘러싸여야 합니다. 선택적 후행 반환 타입으로 끝날 수 있습니다. (C++11부터)
10) 괄호로 묶인 선언자.

모든 경우에서, attr 은 선택적인 attributes 시퀀스입니다. 식별자 바로 뒤에 나타날 때, 이는 선언되는 객체에 적용됩니다.

(since C++11)

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++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 482 C++98 재선언의 선언자에 한정자를 사용할 수 없었음 한정된 선언자 허용
CWG 569 C++98 단독 세미콜론은 유효한 선언이 아니었음 이는 빈 선언이며,
아무런 효과가 없음
CWG 1830 C++98 decl-specifier-seq 내에서 함수 지정자의 반복이 허용됨 반복이 금지됨

참고 항목

C 문서 에 대한 선언