Namespaces
Variants

const_cast conversion

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

서로 다른 cv 한정자를 가진 타입 간 변환을 수행합니다.

목차

구문

const_cast< target-type >( expression )

target-type 타입의 값을 반환합니다.

설명

다음 변환만 const_cast 로 수행할 수 있습니다:

1) 두 개의 유사한(similar) 객체 포인터 또는 데이터 멤버 포인터 타입 T1 T2 에 대해, T1 타입의 prvalue는 T1 T2 가 오직 cv-qualification만 다를 경우(공식적으로, 두 타입의 qualification-decompositions 를 고려했을 때, 모든 i 에 대해 각 P1_i P2_i 와 동일한 경우) T2 로 변환될 수 있습니다.
  • 만약 expression 이 null 포인터 값이면, 결과 또한 null 포인터 값입니다.
  • 만약 expression 이 null 멤버 포인터 값이면, 결과 또한 null 멤버 포인터 값입니다.
  • 만약 expression 이 객체를 가리키면, 결과는 동일한 객체를 가리킵니다.
  • 만약 expression 이 객체의 끝을 지나서 가리키면, 결과는 동일한 객체의 끝을 지나서 가리킵니다.
  • 만약 expression 이 데이터 멤버를 가리키면, 결과는 동일한 데이터 멤버를 가리킵니다.

expression 이 prvalue인 경우에도, temporary materialization 은 수행되지 않습니다.

(C++17부터)
2) 두 개의 객체 타입 T1 T2 에 대해, T1 에 대한 포인터가 const_cast < T2 * > 를 사용하여 "pointer to T2 " 타입으로 명시적으로 변환될 수 있다면, 다음 변환들도 수행될 수 있습니다:
  • T1 타입의 lvalue는 const_cast < T2 & > 를 사용하여 T2 타입의 lvalue로 명시적으로 변환될 수 있습니다.
  • T1 타입의 glvalue는 const_cast < T2 && > 를 사용하여 T2 타입의 xvalue로 명시적으로 변환될 수 있습니다.
  • T1 이 클래스 타입이나 배열 타입인 경우, T1 타입의 prvalue는 const_cast < T2 && > 를 사용하여 T2 타입의 xvalue로 명시적으로 변환될 수 있습니다.
(C++11부터)

결과 참조는 원본 객체를 참조합니다.

(C++17까지)

표현식 이 glvalue인 경우, 결과 참조는 원본 객체를 참조합니다. 그렇지 않으면, 결과 참조는 구체화된 임시 객체 를 참조합니다.

(C++17부터)

모든 형변환 표현식과 마찬가지로, 결과는 다음과 같습니다:

  • target-type 이 lvalue 참조 타입인 경우 lvalue 또는 함수 타입에 대한 rvalue 참조인 경우 (C++11부터) ;
  • target-type 가 객체 타입에 대한 rvalue 참조인 경우 xvalue;
(since C++11)
  • 그렇지 않으면 prvalue입니다.

const 제거 캐스팅

서로 다른 두 타입 T1 T2 에 대해, T1 에서 T2 로의 변환이 constness를 제거한다 는 것은, T2 자격 분해 가 "cv2_0 P2_0 cv2_1 P2_1 ... cv2_n−1 P2_n−1 cv2_n U2" 형태로 존재하고, T1 을 "cv2_0 P1_0 cv2_1 P1_1 ... cv2_n−1 P1_n−1 cv2_n U1"로 변환하는 자격 변환 이 존재하지 않는 경우를 말합니다 (동일한 cv 구성 요소, 다른 P 구성 요소 및 U 구성 요소).

만약 T1* 타입의 prvalue에서 T2* 타입으로의 캐스트가 constness를 제거한다면, T1 타입의 표현식에서 T2 에 대한 참조로의 캐스트도 constness를 제거하게 됩니다.

오직 const_cast 만이 constness를 제거하는 데 사용될 수 있습니다.

"constness를 없애는 캐스팅"은 "volatility를 없애는 캐스팅"을 의미합니다. 왜냐하면 한정 변환(qualification conversion)은 volatility 역시 없앨 수 없기 때문입니다.

참고 사항

함수에 대한 포인터와 멤버 함수에 대한 포인터는 const_cast 의 적용 대상이 아닙니다.

const_cast 는 실제로 const 객체 를 참조하는 비-const 타입의 참조자나 포인터를 형성하거나, 실제로 volatile 객체 를 참조하는 비-volatile 타입의 참조자나 포인터를 형성할 수 있게 합니다. const 객체를 비-const 접근 경로를 통해 수정하거나 volatile 객체를 비-volatile glvalue 를 통해 참조하는 것은 정의되지 않은 행동을 초래합니다.

키워드

const_cast

예제

#include <iostream>
struct type
{
    int i;
    type(): i(3) {}
    void f(int v) const
    {
        // this->i = v;                 // 컴파일 오류: this는 const에 대한 포인터입니다
        const_cast<type*>(this)->i = v; // type 객체가 const가 아닌 경우 OK
    }
};
int main()
{
    int i = 3;                 // i는 const로 선언되지 않음
    const int& rci = i;
    const_cast<int&>(rci) = 4; // OK: i를 수정함
    std::cout << "i = " << i << '\n';
    type t; // 이게 const type t였다면 t.f(4)는 정의되지 않은 동작이 됨
    t.f(4);
    std::cout << "type::i = " << t.i << '\n';
    const int j = 3; // j는 const로 선언됨
    [[maybe_unused]]
    int* pj = const_cast<int*>(&j);
    // *pj = 4;      // 정의되지 않은 동작
    [[maybe_unused]]
    void (type::* pmf)(int) const = &type::f; // 멤버 함수 포인터
    // const_cast<void(type::*)(int)>(pmf);   // 컴파일 오류: const_cast는
                                              // 함수 포인터에서 작동하지 않음
}

출력:

i = 4
type::i = 4

결함 보고서

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

DR 적용 대상 게시된 동작 올바른 동작
CWG 1965 C++11 const_cast 가 배열 prvalue에 대한 rvalue 참조를 바인딩할 수 없었음 해당 참조 바인딩 허용
CWG 2879 C++17 포인터 pvalue 피연산자가 materialized되었음 materialized되지 않음

참고문헌

  • C++23 표준 (ISO/IEC 14882:2024):
  • 7.6.1.11 Const cast [expr.const.cast]
  • C++20 표준(ISO/IEC 14882:2020):
  • 7.6.1.10 Const cast [expr.const.cast]
  • C++17 표준 (ISO/IEC 14882:2017):
  • 8.2.11 Const cast [expr.const.cast]
  • C++14 표준(ISO/IEC 14882:2014):
  • 5.2.11 Const cast [expr.const.cast]
  • C++11 표준(ISO/IEC 14882:2011):
  • 5.2.11 Const cast [expr.const.cast]
  • C++98 표준 (ISO/IEC 14882:1998):
  • 5.2.11 Const cast [expr.const.cast]
  • C++03 표준 (ISO/IEC 14882:2003):
  • 5.2.11 Const cast [expr.const.cast]

참고 항목