const int *: Der Zeiger selbst ist ver?nderlich, aber der Wert, auf den gezeigt wird, ist unver?nderlich
int * const: Der Zeiger selbst ist unver?nderlich und der Wert, auf den gezeigt wird, ist ver?nderlich
Beim Konvertieren von const int * -> int * const wird ein Fehler gemeldet
Konvertierung int * const -> const int * kann durchgeführt werden
Semantisch gesehen ist es einfacher zu verstehen, aber aus formaler Sicht haben beide eine unver?nderliche Menge. Warum ist also bei der Konvertierung eine Richtung m?glich, die andere jedoch nicht? Wenn ich darüber nachdenke, liegt es vielleicht daran, dass Hinweise und Werte nicht auf dem gleichen Niveau sind, aber ich wei? nicht, wie ich es klarstellen soll?
假設(shè)這里討論的是隱式轉(zhuǎn)換(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規(guī)則復(fù)雜些,對于類類型,是否能轉(zhuǎn)換取決于轉(zhuǎn)換構(gòu)造函數(shù)和轉(zhuǎn)換函數(shù)。對于非類類型,不存在頂層const轉(zhuǎn)換一說。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 example, be 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。關(guān)于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 either implicit 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 to function type (8.3.2), an xvalue 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.
這一段約定了隱式轉(zhuǎn)換后的value category。當隱式轉(zhuǎn)換的結(jié)果是prvalue時,不存在const一說;而當結(jié)果是glvalue時,轉(zhuǎn)換的目標類型得是lvalue reference或rvalue reference。在這種情況下,若如下初始化成立,則能轉(zhuǎn)換:
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約束了是否能初始化。這里的規(guī)則類似qualification conversion的規(guī)則。另外這些const已經(jīng)是底層const了。
PS:在qualification conversions處有一個腳注:“These rules ensure that const-safety is preserved by the conversion.”。一切implicit const conversion,約定的也好,假想的也好,只要能保證const的安全性,就沒毛病。如果某個const conversion保證了const的安全性,但是卻因違背了其他某些條款而不能實現(xiàn),那大概這語言藥丸?;?/p>