简体   繁体   中英

Is it temporary materialization conversion applied to the operand of the const_cast

int main(){
  const_cast<int&&>(0);
}

According to expr.const.cast#4

For two object types T1 and T2, if a pointer to T1 can be explicitly converted to the type “pointer to T2” using a const_cast, then the following conversions can also be made:

  • an lvalue of type T1 can be explicitly converted to an lvalue of type T2 using the cast const_cast<T2&>;
  • a glvalue of type T1 can be explicitly converted to an xvalue of type T2 using the cast const_cast<T2&&>; and
  • if T1 is a class type, a prvalue of type T1 can be explicitly converted to an xvalue of type T2 using the cast const_cast<T2&&>.

The result of a reference const_cast refers to the original object if the operand is a glvalue and to the result of applying the temporary materialization conversion otherwise.

Since the operand 0 is a prvalue of type int and the specified type is rvalue reference of type int. Hence, the second bullet can be applied here after performing the temporary materialization conversion that make the origin operand to be a glvalue as per expr#basic.lval-7

Whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion is applied to convert the expression to an xvalue.

However, this snippet is rejected by both Clang and GCC. If we change the operand to int{0}

int main(){
  const_cast<int&&>(int{0});
}

Only GCC accepts the code. But the following code still cannot be compiled by GCC

int main(){
  const_cast<int&&>(int(0));
}

I don't know what's the difference here when the operand is 0 , int{0} , and int(0) respectively. In my mind, they're all prvalue of int type.

typedef int *A[3];  
typedef const int *const CA[3];
int main(){
   A &&r2 = const_cast<A&&>(CA{}); 
}

This code is a formal example of expr.const.cast#3 . Unfortunately, it's rejected by Clang .

I don't know whether it could be considered as a defect of the standard or an incorrect implementation of Clang? I don't know what's the intent of the third bullet of [expr.const.cast#4], why does it special mention the prvalue of class type?(Does it intend to say that only a prvalue of class type will be applied temporary materialization to it? However, it obviously contradicts with the example for prvalue of the array type).

The key here is if T1 is a class type . The type int is not a class type so 4.3 does not apply. If you used a std::string , it would work:

const std::string && x = const_cast<std::string&&>(std::string("foo") + "bar");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM