찾다

 >  Q&A  >  본문

c++ - const int *와 int * const 사이의 유형 변환

const int *: 포인터 자체는 변경할 수 있지만 가리키는 값은 변경할 수 없습니다.

int * const: 포인터 자체는 불변이며, 가리키는 값은 변경 가능합니다

const int * -> int * const를 변환하면 오류가 보고됩니다

int * const -> const int * 변환이 가능합니다

의미적으로 말하면 이해하기 쉽지만 공식적인 관점에서 보면 둘 다 불변의 수량을 가지고 있는데 변환 중에 한 방향은 가능하지만 다른 방향은 가능하지 않은 이유는 무엇입니까? 생각해보면 포인터와 값이 같은 수준이 아니기 때문일 수도 있는데 어떻게 명확하게 설명할 수 있을까요?

为情所困为情所困2780일 전939

모든 응답(1)나는 대답할 것이다

  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-16 13:33:16

    여기에서 논의되는 내용은 암시적 변환(static_cast와 유사)이라고 가정합니다.

    기본 const는 한정 변환을 준수합니다. 대상 유형은 더 한정되어야 합니다. 즉, const는 그 이상만 가능하고 그 이상일 수는 없습니다.

    4.1 표준 변환은 의미가 내장된 암시적 변환입니다. 4절에는 이러한 변환의 전체 집합이 나열되어 있습니다.

    4.4.1 “cv2 T”가 “cv1 T”보다 cv에 더 적합한 경우 “cv1 T에 대한 포인터” 유형의 prvalue는 “cv2 T에 대한 포인터” 유형의 prvalue로 변환될 수 있습니다.

    최상위 const 규칙은 클래스 유형의 경우 변환 가능 여부가 변환 생성자 및 변환 함수에 따라 더 복잡합니다. 클래스가 아닌 유형의 경우 최상위 const 변환과 같은 것이 없습니다. 4절 표준 변환은 최상위 const에 대해 아무 말도 하지 않습니다.


    여기에서는 최상위 const와 관련된 몇 가지 상황에 대해 논의합니다.

    표현:

    5.8 [...] [참고: 표현식이 prvalue로 변환될 때 클래스가 아닌 유형의 표현식 유형에서 cv 한정자가 제거되기 때문에 예를 들어 const int 유형의 lvalue 표현식은 다음과 같을 수 있습니다. int 유형의 prvalue 표현식이 필요한 경우에 사용됩니다. —참고]

    과제:

    3.10.1 [...] 내장 할당 연산자는 왼쪽 피연산자가 lvalue이고 오른쪽 피연산자가 prvalue이고 결과로 lvalue를 생성할 것으로 예상합니다.

    3.10.2 prvalue가 예상되는 컨텍스트에 glvalue가 나타날 때마다 glvalue는 prvalue로 변환됩니다. [...]

    3.10.4 클래스 Prvalue는 cv-qualified 유형을 가질 수 있으며, non-class prvalue는 항상 cv-qualified 유형을 가질 수 있습니다.

    초기화:

    8.5.16 [...] [ 참고: "cv1 T" 유형의 표현식은 cv 한정자 cv1 및 cv2와 독립적으로 "cv2 T" 유형의 객체를 초기화할 수 있습니다.

    즉, 필요한 것이 prvalue인 경우 const prvalue가 없습니다. glvalue와 관련하여 다음과 같은 규칙이 있습니다.

    4.3 표현식 e는 선언 T t=e;가 고안된 임시 변수 t(8.5)에 대해 올바른 형식인 경우에만 암시적으로 T 유형으로 변환될 수 있습니다.[...] 암시적 효과 변환은 선언 및 초기화를 수행한 다음 변환 결과로 임시 변수를 사용하는 것과 동일합니다. T가 lvalue 참조 유형이거나 함수 유형(8.3.2)에 대한 rvalue 참조인 경우 결과는 xvalue입니다. T가 객체 유형에 대한 rvalue 참조이고 그렇지 않은 경우 표현식 e는 초기화에서 glvalue로 사용되는 경우에만 glvalue로 사용됩니다.

    이 단락은 암시적 변환 후의 값 범주를 규정합니다. 암시적 변환 결과가 prvalue인 경우 const는 없으며 결과가 glvalue인 경우 변환 대상 유형은 lvalue 참조 또는 rvalue 참조여야 합니다. 이 경우 다음 초기화가 유지되면 변환될 수 있습니다.

    T &t = e;

    T &&t = e;

    const T &t = e;
    const T &&t = e;

    8.5.3.4 "cv1 T1" 및 "cv2 T2" 유형이 주어지면 T1이 T2와 동일한 유형이거나 T1이 T2의 기본 클래스인 경우 "cv1 T1"은 "cv2 T2"와 참조 관련됩니다. T1”은 T1이 T2와 참조 관련되어 있고 cv1이 cv2와 동일하거나 더 큰 cv 자격을 갖춘 경우 “cv2 T2”와 참조 호환 가능합니다.

    참조 호환은 초기화 가능 여부를 제한합니다. 여기의 규칙은 자격 전환 규칙과 유사합니다. 또한 이러한 const는 이미 기본 const입니다.

    PS: 자격 변환에는 다음과 같은 각주가 있습니다. "이 규칙은 변환에 의해 const 안전성이 유지되도록 보장합니다." 합의된 것이든 가상이든 상관없이 모든 암시적 const 변환은 const의 안전성을 보장할 수 있는 한 괜찮습니다. const 변환이 const의 안전성을 보장하지만 다른 용어를 위반하여 구현할 수 없다면 이는 아마도 언어 약일 것입니다. 재미있다

    회신하다
    0
  • 취소회신하다