Namespaces
Variants

Other operators

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
연산자
이름
구문 오버로드 가능 프로토타입 예시 ( class T 의 경우)
클래스 정의 내부 클래스 정의 외부
함수 호출 a(a1, a2) 가능 R T :: operator ( ) ( Arg1 & a1, Arg2 & a2, ... ) ; 해당 없음
쉼표 a, b 가능 T2 & T :: operator , ( T2 & b ) ; T2 & operator, ( const T & a, T2 & b ) ;
조건 연산자 a ? b : c 불가능 해당 없음 해당 없음

함수 호출 연산자는 모든 객체에 대해 함수 의미론을 제공합니다.

조건부 연산자 (일반적으로 삼항 조건 연산자 라고 불림)는 첫 번째 표현식의 불리언 값을 검사하고, 그 결과값에 따라 두 번째 또는 세 번째 표현식을 평가하여 반환합니다.

목차

내장 함수 호출 연산자

함수 호출 표현식은 다음과 같은 형식을 갖습니다:

함수  ( arg1 , arg2 , arg3 , ... )
function - 함수 표현식 타입 또는 함수 포인터 타입
arg1 , arg2 , arg3 , ... - 임의의 표현식들로 구성된 가능한 빈 목록 또는 중괄호로 둘러싸인 초기화 리스트 (C++11부터) , 단 최상위 레벨에서 쉼표 연산자는 모호성을 피하기 위해 허용되지 않음

비멤버 함수 또는 static member function 에 대한 호출에서, function 은 함수를 참조하는 lvalue(이 경우 function-to-pointer conversion 이 억제됨)이거나 함수 포인터 타입의 prvalue일 수 있습니다.

function 으로 지정된 함수(또는 멤버) 이름은 오버로드될 수 있으며, 오버로드 해결 규칙이 어떤 오버로드를 호출할지 결정하는 데 사용됩니다.

만약 function 이 멤버 함수를 지정한다면, 해당 함수는 virtual일 수 있으며, 이 경우 해당 함수의 최종 오버라이더가 런타임에 동적 디스패치를 사용하여 호출됩니다.

각 함수 매개변수는 필요한 경우 암시적 변환 후 해당 인수로 초기화됩니다.

  • 해당 인수가 없는 경우, 해당 기본 인수 가 사용되며, 기본 인수도 없는 경우 프로그램은 잘못된 형식입니다.
  • 호출이 멤버 함수에 대한 것이라면, 현재 객체에 대한 this 포인터는 함수가 기대하는 this 포인터로 명시적 캐스트된 것처럼 변환됩니다.
  • 각 매개변수의 초기화 및 소멸은 함수 호출이 나타나는 전체 표현식 의 컨텍스트에서 발생합니다. 이는 예를 들어 매개변수의 생성자나 소멸자가 예외를 발생시키는 경우, 호출된 함수의 함수 try 블록 이 고려되지 않음을 의미합니다.

함수가 가변 인자 함수인 경우, 기본 인자 승격 이 생략 부호 매개변수와 일치하는 모든 인수에 적용됩니다.

매개변수가 정의된 함수가 종료될 때 파괴되는지, 아니면 포함하는 전체 표현식의 끝에서 파괴되는지는 구현에 따라 정의됩니다. 매개변수는 항상 생성된 순서의 역순으로 파괴됩니다.

함수 호출 표현식의 반환 타입은 선택된 함수의 반환 타입으로, 정적 바인딩을 사용하여 결정됩니다( virtual 키워드는 무시됨). 실제로 호출되는 오버라이딩 함수가 다른 타입을 반환하더라도 마찬가지입니다. 이를 통해 오버라이딩 함수들은 기본 함수가 반환하는 반환 타입에서 파생된 클래스의 포인터나 참조를 반환할 수 있습니다. 즉, C++는 공변 반환 타입 을 지원합니다. 만약 function 이 소멸자를 지정하는 경우, 반환 타입은 void 입니다.

클래스 타입 X 의 객체가 함수에 전달되거나 함수에서 반환될 때, X 의 모든 복사 생성자, 이동 생성자, 소멸자가 trivial이거나 삭제된 상태이고, X 에 삭제되지 않은 복사 또는 이동 생성자가 적어도 하나 이상 존재하는 경우, 구현체는 함수 매개변수나 결과 객체를 보관하기 위해 임시 객체를 생성할 수 있습니다.

임시 객체는 각각 함수 인자나 반환값으로부터 생성되며, 함수의 매개변수나 반환 객체는 삭제되지 않은 trivial 생성자를 사용하여 임시 객체를 복사하는 것처럼 초기화됩니다 (해당 생성자가 접근 불가능하거나 오버로드 해결에 의해 객체의 복사나 이동을 수행하도록 선택되지 않을 경우에도).

이를 통해 std::complex std::span 과 같은 작은 클래스 타입의 객체를 레지스터를 통해 함수에 전달하거나 반환할 수 있습니다.

(C++17부터)

함수 호출 표현식의 값 범주는 함수가 lvalue 참조 또는 함수에 대한 rvalue 참조를 반환하면 lvalue이고, 함수가 객체에 대한 rvalue 참조를 반환하면 xvalue이며, 그 외의 경우에는 prvalue입니다. 함수 호출 표현식이 객체 유형의 prvalue인 경우, 완전한 유형을 가져야 합니다 complete type (단, decltype 의 피연산자로 사용되는 경우(또는 built-in comma operator 의 오른쪽 피연산자로 사용되어 decltype 의 피연산자가 되는 경우는 제외) (C++11부터) .

호출된 함수가 정상적으로 종료되면, 함수의 모든 사후 조건 단언문 순차적으로 평가 됩니다. 구현체가 결과 값을 보유하기 위해 임시 객체 를 도입하는 경우, 각 사후 조건 단언문의 평가 E 에 대해:

  • E 는 해당 임시 객체들 또는 결과 객체의 초기화와 관련하여 비결정적 순서 로 수행됩니다.
  • E 는 함수 매개변수의 소멸보다 먼저 순서 가 지정됩니다.
(C++26부터)

함수 호출 표현식은 구문상 값 초기화 T ( ) 와 유사하며, 함수 방식 캐스트 표현식 T ( A1 ) 및 임시 객체의 직접 초기화 T ( A1, A2, A3, ... ) 와도 유사합니다. 여기서 T 는 타입의 이름입니다.

#include <cstdio>
struct S
{
    int f1(double d)
    {
        return printf("%f \n", d); // 가변 인자 함수 호출
    }
    int f2()
    {
        return f1(7); // 멤버 함수 호출, this->f1()과 동일
                      // 정수 인자가 double로 변환됨
    }
};
void f()
{
    puts("function called"); // 함수 호출
}
int main()
{
    f();    // 함수 호출
    S s;
    s.f2(); // 멤버 함수 호출
}

출력:

function called
7.000000

내장 콤마 연산자

콤마 표현식은 다음과 같은 형식을 갖습니다:

E1 , E2

콤마 표현식 E1, E2 에서, E1 표현식이 평가된 후 그 결과는 폐기됩니다 (단, 클래스 타입인 경우 포함하는 전체 표현식이 끝날 때까지 소멸되지 않음 ). 그리고 그 부수 효과(side effects)가 완료된 후에 E2 표현식의 평가가 시작됩니다 (사용자 정의 operator, 는 순서 보장을 할 수 없음에 유의) (C++17까지) .

쉼표 표현식의 결과 타입, 값, 값 범주는 정확히 두 번째 피연산자인 E2 의 타입, 값, 값 범주와 동일합니다. 만약 E2 가 임시 표현식인 경우 (C++17부터) , 표현식의 결과는 해당 임시 표현식입니다 (C++17부터) . 만약 E2 가 비트 필드인 경우, 결과는 비트 필드입니다.

함수 인수 목록( f ( a, b, c ) ) 및 초기화 목록 int a [ ] = { 1 , 2 , 3 } 등 다양한 쉼표로 구분된 목록에서 사용되는 쉼표는 쉼표 연산자가 아닙니다. 이러한 맥락에서 쉼표 연산자를 사용해야 하는 경우 괄호로 묶어야 합니다: f ( a, ( n ++ , n + b ) , c ) .

괄호 없는 쉼표 표현식을 subscript operator 의 두 번째(오른쪽) 인수로 사용하는 것은 deprecated되었습니다.

예를 들어, a [ b, c ] 는 deprecated되었으며, a [ ( b, c ) ] 는 그렇지 않습니다.

(C++20부터)
(C++23 이전)

괄호 없는 쉼표 표현식은 subscript operator 의 두 번째(오른쪽) 인수로 사용할 수 없습니다. 예를 들어, a [ b, c ] 는 잘못된 형식이거나 a. operator [ ] ( b, c ) 와 동일합니다.

쉼표 표현식을 subscript로 사용할 때는 괄호가 필요합니다. 예를 들어, a [ ( b, c ) ] 와 같이 사용해야 합니다.

(C++23부터)
#include <iostream>
int main()
{
    // 쉼표는 언어 문법이 단 하나의 표현식만 허용하는 곳에서
    // 여러 표현식을 실행하기 위해 자주 사용됩니다:
    // * for 루프의 세 번째 구성 요소에서
    for (int i = 0, j = 10; i <= j; ++i, --j)
    //            ^목록 구분 기호      ^쉼표 연산자
        std::cout << "i = " << i << " j = " << j << '\n';
    // * return 문에서
    // return log("an error!"), -1;
    // * 초기화 표현식에서
    // MyClass(const Arg& arg)
    // : member{ throws_if_bad(arg), arg }
    // 등
    // 쉼표 연산자는 연결될 수 있으며, 마지막(가장 오른쪽) 표현식의
    // 결과가 전체 체인의 결과가 됩니다:
    int n = 1;
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2 * n);
    // m은 이제 6
    std::cout << "m = " << (++m, m) << '\n';
}

출력:

i = 0 j = 10
i = 1 j = 9
i = 2 j = 8
i = 3 j = 7
i = 4 j = 6
i = 5 j = 5
n = 2
m = 7

조건 연산자

조건부 연산자 표현식의 형식은 다음과 같습니다

E1 ? E2 : E3

E1 이 평가되고 상황에 맞게 변환되어 bool 이 됩니다. 결과가 true 인 경우, 조건부 표현식의 결과는 E2 의 값입니다. 그렇지 않은 경우 조건부 표현식의 결과는 E3 의 값입니다.

조건부 표현식 E1 ? E2 : E3 의 타입과 값 범주는 다음과 같이 결정됩니다:

Stage 1

만약 E2 E3 모두 void 타입이면, 결과는 rvalue (C++11 이전) prvalue (C++11 이후) void 타입입니다.

E2 E3 중 정확히 하나가 void 타입인 경우:

  • 해당 피연산자가 void 타입이고 (괄호로 둘러싸인 경우도 포함) throw expression 인 경우, 결과는 다른 피연산자의 타입과 값 범주를 가집니다 [1] . 다른 피연산자가 bit-field 인 경우, 결과 또한 bit-field입니다.
  • 그렇지 않은 경우, 프로그램은 ill-formed입니다.

E2 E3 중 어느 것도 void 타입이 아닌 경우, 다음 단계로 진행합니다.

2 + 2 == 4 ? throw 123 : throw 456; // 결과의 타입은 "void"입니다
2 + 2 != 4 ? "OK" : throw "error";  // 결과의 타입은 "const char[3]"입니다
                                    // 항상 예외가 발생하더라도

Stage 2

만약 E2 또는 E3 lvalue 비트 필드 (C++11 이전) 동일한 값 범주의 glvalue 비트 필드 (C++11 이후) 이고 각각 cv1 T cv2 T 타입인 경우, 피연산자들은 나머지 처리 과정에서 cv T 타입으로 간주되며, 여기서 cv cv1 cv2 의 합집합입니다.

만약 E2 E3 의 타입이 다르고, 다음 조건 중 하나라도 충족되면 3단계로 진행합니다:

  • E2 E3 중 적어도 하나가 (cv 한정자가 있을 수 있는) 클래스 타입입니다.
  • E2 E3 모두 동일한 타입의 lvalue (C++11 이전) 동일한 값 범주와 동일한 타입의 glvalue (C++11 이후) 입니다(cv 한정자는 제외).

그렇지 않으면, 4단계로 진행합니다.

Stage 3

피연산자 표현식 X 의 타입 TX 에서 피연산자 표현식 Y 의 타입 TY 와 관련된 대상 타입 으로의 암시적 변환 시퀀스 [2] 를 다음과 같이 형성하려고 시도합니다:

  • 만약 Y 가 lvalue인 경우, 대상 타입은 TY& 이지만, 참조가 lvalue에 (C++11 이전) glvalue에 (C++11 이후) 직접 바인딩 될 때만 암시적 변환 시퀀스가 형성될 수 있습니다.
  • 만약 Y 가 xvalue라면, 대상 타입은 TY&& 이지만, 참조가 직접 바인딩될 수 있는 경우에만 암시적 변환 시퀀스가 형성될 수 있습니다.
(C++11부터)
  • 만약 Y rvalue인 경우 (C++11 이전) prvalue인 경우 (C++11 이후) 또는 위의 변환 시퀀스 중 어느 것도 형성될 수 없고, TX TY 중 적어도 하나가 (가능한 cv-qualified) 클래스 타입인 경우:
    • 만약 TX TY 가 동일한 클래스 타입인 경우 (cv-qualification 무시):
      • 만약 TY TX 이상으로 cv-qualified라면, 대상 타입은 TY 입니다.
      • 그렇지 않으면, 변환 시퀀스가 형성되지 않습니다.
    • 그렇지 않고, 만약 TY TX 의 기본 클래스인 경우, 대상 타입은 TX 의 cv-qualifier를 가진 TY 입니다.
    • 그렇지 않으면, 대상 타입은 Y 에 lvalue-to-rvalue, array-to-pointer, function-to-pointer 표준 변환 을 적용한 후의 Z 값의 타입입니다.
  • 그렇지 않으면, 변환 시퀀스가 형성되지 않습니다.

이 과정을 통해 E2 로부터 E3 에 대해 결정된 대상 타입으로의 암시적 변환 시퀀스 형성 가능 여부가 판단되며, 그 역방향도 마찬가지로 확인됩니다.

  • 변환 순서를 형성할 수 없는 경우, 다음 단계로 진행합니다.
  • 정확히 하나의 변환 순서만 형성될 수 있는 경우:
    • 변환 순서가 모호한 경우, 프로그램은 올바르지 않은 형태입니다.
    • 그렇지 않은 경우, 해당 변환이 선택된 피연산자에 적용되며 변환된 피연산자는 원본 피연산자 대신 남은 처리 과정에 사용되고 다음 단계로 진행합니다.
  • 두 순서 모두 형성될 수 있는 경우, 프로그램은 올바르지 않은 형태입니다.
struct A {};
struct B : A {};
using T = const B;
A a = true ? A() : T(); // Y = A(), TY = A, X = T(), TX = const B, Target = const A

단계 4

만약 E2 E3 가 같은 타입의 lvalue라면, 결과는 해당 타입의 lvalue이며, E2 E3 중 적어도 하나가 비트 필드인 경우 비트 필드입니다.

(C++11 이전)

만약 E2 E3 가 같은 타입과 같은 값 범주를 가진 glvalue라면, 결과는 같은 타입과 값 범주를 가지며, E2 E3 중 적어도 하나가 비트 필드인 경우 비트 필드입니다.

(C++11 이후)

그렇지 않으면 결과는 an rvalue (until C++11) a prvalue (since C++11) 입니다.

  • 만약 E2 E3 가 같은 타입을 가지지 않고, 둘 중 하나가 (cv-qualified 가능성 있는) 클래스 타입을 가지는 경우, 5단계로 진행합니다.
  • 그렇지 않으면, 6단계로 진행합니다.

Stage 5

오버로드 해결 내장 후보 를 사용하여 피연산자를 내장 타입으로 변환하려고 시도하면서 수행됩니다:

  • 오버로드 해결이 실패할 경우, 프로그램은 형식에 맞지 않습니다.
  • 그렇지 않으면, 선택된 변환이 적용되고 변환된 피연산자는 원본 피연산자 대신 나머지 과정에서 사용됩니다. 다음 단계로 진행합니다.

Stage 6

배열-포인터 및 함수-포인터 변환이 (변환된 가능성이 있는) E2 E3 에 적용됩니다. 이러한 변환 후에 다음 조건 중 적어도 하나가 충족되어야 하며, 그렇지 않으면 프로그램이 잘못된 형태입니다:

  • E2 E3 가 동일한 타입을 가집니다. 이 경우 결과는 해당 타입이며 선택된 피연산자를 사용하여 복사 초기화 됩니다.
  • E2 E3 모두 산술 타입이나 열거형 타입을 가집니다. 이 경우 일반 산술 변환 이 적용되어 공통 타입으로 변환되며 결과는 해당 타입입니다.
  • E2 E3 중 적어도 하나가 포인터입니다. 이 경우 lvalue-to-rvalue, 포인터 , 함수 포인터 (C++17부터) 및 한정 변환이 적용되어 복합 포인터 타입 으로 변환되며 결과는 해당 타입입니다.
  • E2 E3 중 적어도 하나가 멤버 포인터입니다. 이 경우 lvalue-to-rvalue, 멤버 포인터 , 함수 포인터 (C++17부터) 및 한정 변환이 적용되어 복합 포인터 타입 으로 변환되며 결과는 해당 타입입니다.
  • E2 E3 모두 null 포인터 상수이며, 둘 중 적어도 하나가 std::nullptr_t 타입인 경우. 이 경우 결과는 std::nullptr_t 타입입니다.
(C++11부터)
int* intPtr;
using Mixed = decltype(true ? nullptr : intPtr);
static_assert(std::is_same_v<Mixed, int*>); // nullptr가 int*로 변환됨
struct A
{
    int* m_ptr;
} a;
int* A::* memPtr = &A::m_ptr; // memPtr는 A의 멤버 m_ptr에 대한 포인터
// memPtr는 nullptr를 A의 멤버 m_ptr에 대한 포인터 타입으로 만듦
static_assert(std::is_same_v<decltype(false ? memPtr : nullptr), int*A::*>);
// a.*memPtr는 이제 단순히 int 포인터이며 nullptr도 int 포인터로 변환됨
static_assert(std::is_same_v<decltype(false ? a.*memPtr : nullptr), int*>);
  1. 이러한 조건부 연산자는 C++14 이전의 C++11 constexpr 프로그래밍 에서 흔히 사용되었습니다.
  2. 멤버 접근 , 변환 함수가 삭제되었는지 여부 (C++11부터) 및 피연산자가 비트 필드인지 여부는 무시됩니다.

조건부 연산자의 결과 타입은 이진 타입 특성 std::common_type 으로도 접근할 수 있습니다.

(since C++11)

오버로드

모든 승격된 산술 타입 쌍 L R , 그리고 P 가 포인터, 멤버 포인터, 또는 범위 열거형 타입인 모든 타입 P 에 대해, 다음 함수 시그니처들이 오버로드 해결에 참여합니다:

LR 연산자 ?: ( bool , L, R ) ;
P 연산자 ?: ( bool , P, P ) ;

여기서 LR은 일반 산술 변환 L R 에 수행된 결과입니다.

연산자 " ?: "는 오버로드할 수 없으며, 이러한 함수 시그니처는 오버로드 해결을 목적으로만 존재합니다.

#include <iostream>
#include <string>
struct Node
{
    Node* next;
    int data;
    // deep-copying copy constructor
    Node(const Node& other)
        : next(other.next ? new Node(*other.next) : NULL)
        , data(other.data)
    {}
    Node(int d) : next(NULL), data(d) {}
    ~Node() { delete next; }
};
int main()
{   
    // simple rvalue example
    int n = 1 > 2 ? 10 : 11;  // 1 > 2 is false, so n = 11
    // simple lvalue example
    int m = 10; 
    (n == m ? n : m) = 7; // n == m is false, so m = 7
    //output the result
    std::cout << "n = " << n << "\nm = " << m;
}

출력:

n = 11
m = 7

표준 라이브러리

표준 라이브러리의 많은 클래스들은 함수 객체로 사용되도록 operator() 를 오버로드합니다.

객체 또는 배열을 삭제함
( std::default_delete<T> 의 public 멤버 함수)
두 인자의 합을 반환합니다
( std::plus<T> 의 public 멤버 함수)
두 인자의 차이를 반환합니다
( std::minus<T> 의 public 멤버 함수)
두 인수의 곱을 반환합니다
( std::multiplies<T> 의 public member function)
첫 번째 인자를 두 번째 인자로 나눈 결과를 반환합니다
( std::divides<T> 의 public 멤버 함수 )
첫 번째 인자를 두 번째 인자로 나눈 나머지를 반환합니다
( std::modulus<T> 의 public 멤버 함수)
인수의 부정을 반환합니다
( std::negate<T> 의 public member function)
인수가 동일한지 확인합니다
( std::equal_to<T> 의 public 멤버 함수)
인수가 서로 다른지 확인합니다
( std::not_equal_to<T> 의 public member function)
첫 번째 인수가 두 번째 인수보다 큰지 확인합니다
( std::greater<T> 의 public member function )
첫 번째 인수가 두 번째 인수보다 작은지 확인합니다
( std::less<T> 의 public member function)
첫 번째 인수가 두 번째 인수보다 크거나 같은지 확인합니다
( std::greater_equal<T> 의 public member function)
첫 번째 인수가 두 번째 인수보다 작거나 같은지 확인합니다
( std::less_equal<T> 의 public member function)
두 인수의 논리 AND를 반환합니다
( std::logical_and<T> 의 public 멤버 함수)
두 인수의 논리적 OR을 반환합니다
( std::logical_or<T> 의 public 멤버 함수)
인수의 논리적 NOT을 반환합니다
( std::logical_not<T> 의 public member function)
두 인수의 비트 AND 연산 결과를 반환합니다
( std::bit_and<T> 의 public member function)
두 인수의 비트 OR 연산 결과를 반환합니다
( std::bit_or<T> 의 public 멤버 함수)
두 인수의 비트별 XOR 연산 결과를 반환합니다
( std::bit_xor<T> 의 public 멤버 함수)
저장된 predicate 호출 결과의 논리적 보수를 반환합니다
( std::unary_negate<Predicate> 의 public member function)
저장된 predicate 호출 결과의 논리적 보수를 반환합니다
( std::binary_negate<Predicate> 의 public member function)
저장된 함수를 호출합니다
( std::reference_wrapper<T> 의 public 멤버 함수)
대상 호출
( std::function<R(Args...)> 의 public 멤버 함수)
대상 호출
( std::move_only_function 의 public 멤버 함수)
대상 호출
( std::copyable_function 의 public 멤버 함수)
코루틴의 실행을 재개함
( std::coroutine_handle<Promise> 의 public member function)
이 로캘의 collate 패싯을 사용하여 두 문자열을 사전식으로 비교합니다
( std::locale 의 public member function)
value_type 타입의 두 값을 비교합니다
( std::map<Key,T,Compare,Allocator>::value_compare 의 public member function)
value_type 타입의 두 값을 비교합니다
( std::multimap<Key,T,Compare,Allocator>::value_compare 의 public 멤버 함수)
함수 실행
( std::packaged_task<R(Args...)> 의 public 멤버 함수)
엔진의 상태를 진행시키고 생성된 값을 반환합니다
( std::linear_congruential_engine<UIntType,a,c,m> 의 public 멤버 함수)
(C++11)
분포에서 다음 난수를 생성함
( std::uniform_int_distribution<IntType> 의 public 멤버 함수)

표준 라이브러리의 어떤 클래스도 쉼표 연산자를 오버로드하지 않습니다. Boost 라이브러리는 operator, boost.assign , boost.spirit 및 다른 라이브러리에서 사용합니다. 데이터베이스 접근 라이브러리 SOCI 또한 operator, 를 오버로드합니다.

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 446 C++98 조건부 연산자에서 lvalue-to-rvalue 변환을 위해 임시 객체가 생성되는지 여부가 명시되지 않음 연산자가 클래스 rvalue를 반환하는 경우 항상 임시 객체 생성
CWG 462 C++98 쉼표 연산자의 두 번째 피연산자가 임시 객체일 때, 쉼표 표현식의 결과가 참조에 바인딩될 경우 해당 임시 객체의 수명이 연장되는지 여부가 명시되지 않음 이 경우 쉼표 표현식의 결과가 임시 객체임 (따라서 수명이 연장됨)
CWG 587 C++98 조건부 연산자의 두 번째와 세 번째 피연산자가 cv-한정자를 제외하고 동일한 타입의 lvalue일 때, 이 피연산자들이 클래스 타입을 가지면 결과가 lvalue이고 그렇지 않으면 rvalue였음 이 경우 결과는 항상 lvalue
CWG 1029 C++98 소멸자 호출의 타입이 명시되지 않음 void 로 명시됨
CWG 1550 C++98 다른 피연산자가 non- void 일 때 조건식에서 괄호로 묶인 throw 표현식이 허용되지 않음 허용됨
CWG 1560 C++98 조건부 연산자의 void 피연산자가 다른 피연산자에 대해 불필요한 lvalue-to-rvalue 변환을 유발하여 항상 rvalue 결과를 생성함 void 를 포함하는 조건식이 lvalue일 수 있음
CWG 1642 C++98 함수 호출 표현식에서 function 표현식이 함수 포인터 lvalue일 수 있었음 허용되지 않음
CWG 1805 C++98 암시적 변환 시퀀스의 대상 타입을 결정할 때 Y Z 로 변환하는 방법이 불명확함 명확하게 지정됨
CWG 1895 C++98
C++11
조건식에서 삭제된(C++11) 또는 접근 불가능한(C++98) 변환 함수가 변환을 방지하는지 불명확하고, 기본 클래스에서 파생 클래스 prvalue로의 변환이 고려되지 않음 오버로드 해결과 동일하게 처리됨
CWG 1932 C++98 동일 타입 비트 필드가 조건식에서 누락됨 기본 타입으로 처리됨
CWG 2226 C++11 조건부 연산자의 다른 피연산자 대상 타입을 결정할 때, 해당 피연산자가 lvalue이면 참조가 xvalue에 바인딩될 수 없었음 허용됨
CWG 2283 C++17 함수 호출 연산자에 대한 타입 완전성 요구사항이 P0135R1 에 의해 실수로 제거됨 요구사항 복원됨
CWG 2321 C++98 조건부 연산자의 다른 피연산자 대상 타입을 결정할 때, 파생 클래스 타입이 더 적은 cv-한정을 가진 기본 클래스 타입으로 변환될 수 없었음 파생 클래스 피연산자의 cv-한정을 가진 기본 클래스 타입으로 변환 허용
CWG 2715 C++98 각 매개변수의 초기화와 소멸이 호출 함수의 컨텍스트 내에서 발생함 (해당 함수가 존재하지 않을 수 있음) [1] 포함하는 전체 표현식의 컨텍스트 내에서 발생함
CWG 2850 C++98 매개변수의 소멸 순서가 불명확함 명확하게 지정됨
CWG 2865 C++98 TX TY 가 동일한 클래스 타입이고 TX TY 보다 더 많은 cv-한정을 가질 때, prvalue Y 에서 암시적 변환 시퀀스가 여전히 형성될 수 있었음 이 경우 변환 시퀀스가 형성되지 않음
CWG 2906 C++98 조건부 연산자의 rvalue 결과 경우에 lvalue-to-rvalue 변환이 무조건적으로 적용됨 일부 경우에만 적용됨
  1. 예를 들어, 네임스페이스 범위 변수의 초기화자에서 함수를 호출할 수 있으며, 이 컨텍스트에서는 "호출 함수"가 존재하지 않습니다.

참고 항목

연산자 우선순위
연산자 오버로딩

일반 연산자
assignment increment
decrement
arithmetic logical comparison member
access
other

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

함수 호출

a ( ... )
콤마

a, b
조건부 연산자

a ? b : c
특수 연산자

static_cast 관련된 타입 간 변환을 수행
dynamic_cast 상속 계층 구조 내에서 변환을 수행
const_cast cv -한정자를 추가하거나 제거
reinterpret_cast 관련 없는 타입 간 변환을 수행
C-style cast static_cast , const_cast , 그리고 reinterpret_cast 의 혼합으로 타입 변환을 수행
new 동적 저장 기간을 가진 객체를 생성
delete 이전에 new 표현식으로 생성된 객체를 파괴하고 획득한 메모리 영역을 해제
sizeof 타입의 크기를 조회
sizeof... pack 의 크기를 조회 (C++11부터)
typeid 타입의 타입 정보를 조회
noexcept 표현식이 예외를 throw할 수 있는지 확인 (C++11부터)
alignof 타입의 정렬 요구사항을 조회 (C++11부터)

C 문서 참조: Other operators