搜尋

首頁  >  問答  >  主體

c++ - const int * 和 int * const 的型別轉換

const int * :指標本身可變,指向的值不可變

int * const :指標本身不可變,指向的值可變

轉換 const int * -> int * const 會報錯誤

轉換 int * const -> const int * 可以進行

從語意上來講比較好理解,但從形式上來看,兩者分別都有一個不可變的量,那為什麼轉化時一個方向可行,而另一個不可行?考慮了一下,可能源自於 指標和值不是一個層次上的東西 ,但又不知道該怎麼說清楚呢?

为情所困为情所困2780 天前938

全部回覆(1)我來回復

  • 过去多啦不再A梦

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

    假設這裡討論的是隱式轉換(static_cast同理):

    底層const遵從qualification conversions:目標類型必須more qualifed。就是const只能多不能少。

    4.1 Standard conversions are implicit conversions with built-in meaning. Clause 4 enumerates the full set of such conversions.

    4.4.1 A prvalue of type “pointer to cv1 T” can be converted to a prvalue of type “pointer to cv2 T” if “cv2 T” is more cv-qualified than “cv1 T”.

    頂層const規則複雜些,對於類別類型,是否能轉換取決於轉換構造函數和轉換函數。對於非類別類型,不存在頂層const轉換一說。 Clause 4 standard conversions對於頂層const隻字未提。


    在這裡另討論幾種有頂層const參與的情況:

    表達式:

    5.8 [...] [Note: Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue expression of type const int can for a prvalue, an lvalue expression of type const intcan, for example, for examp used where a prvalue expression of type int is required. —end note]

    賦值:

    3.10.1 [...] the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result.

    3.10.2 Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue; [...]

    3.10.4 Class prvalues can have cv-qualified types; non-class prvalues always have cv-unqualified types.

    初始化:

    8.5.16 [...] [ Note: An expression of type “cv1 T” can initialize an object of type “cv2 T” independently of the cv-qualifiers cv1 and cv2. [...]

    也就是說當需求的是prvalue時,不存在const prvalue。關於glvalue,有以下約定:

    4.3 An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t (8.5).[...] The effect of some invented temporary variable t (8.5).[...] The implicect ei ther conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion. The result is an lvalue if T is an lvalue reference type or an rvalue reference function . if T is an rvalue reference to object type, and a prvalue otherwise. The expression e is used as a glvalue if and only if the initialization uses it as a glvalue.

    這一段約定了隱式轉換後的value category。當隱式轉換的結果是prvalue時,不存在const一說;而當結果是glvalue時,轉換的目標型別得是lvalue reference或rvalue reference。在這種情況下,若如下初始化成立,則能轉換:

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

    8.5.3.4 Given types “cv1 T1” and “cv2 T2,” “cv1 T1” is reference-related to “cv2 T2” if T1 is the same type as T2, or T1 is a base class of T2. “cv1 T1” is reference-compatible with “cv2 T2” if T1 is reference-related to T2 and cv1 is the same cv-qualification as, or greater cv-qualification than, cv2.

    reference-compatible約束了是否能初始化。這裡的規則類似qualification conversion的規則。另外這些const已經是底層const了。

    PS:在qualification conversions處有一個註腳:「These rules ensure that const-safety is preserved by the conversion.」。一切implicit const conversion,約定的也好,假想的也好,只要能確保const的安全性,就沒毛病。如果某個const conversion保證了const的安全性,但是卻因違背了其他某些條款而不能實現,那大概這語言藥丸。滑稽

    回覆
    0
  • 取消回覆