int main(){
const_cast<int&&>(0);
}
Согласно expr.const.cast № 4
Для двух типов объектов T1 и T2, если указатель на T1 может быть явно преобразован в тип «указатель на T2» с помощью const_cast, тогда также могут быть выполнены следующие преобразования:
- lvalue типа T1 может быть явно преобразовано в lvalue типа T2, используя приведение const_cast ‹T2 &›;
- glvalue типа T1 может быть явно преобразован в xvalue типа T2, используя приведение const_cast ‹T2 &&›; а также
- если T1 является типом класса, prvalue типа T1 может быть явно преобразовано в xvalue типа T2, используя приведение const_cast ‹T2 &&›.
Результат ссылки const_cast относится к исходному объекту, если операнд является значением glvalue, и к результату применения преобразования временной материализации в противном случае.
Поскольку операнд 0 - это prvalue типа int, а указанный тип - это ссылка rvalue типа int. Следовательно, второй пункт может быть применен здесь после выполнения временного преобразования материализации, при котором операндом источника будет значение gl согласно expr # basic.lval-7
Каждый раз, когда prvalue появляется как операнд оператора, который ожидает glvalue для этого операнда, применяется временное преобразование материализации для преобразования выражения в xvalue.
Однако этот фрагмент отклонен как Clang, так и GCC. Если мы изменим операнд на int{0}
int main(){
const_cast<int&&>(int{0});
}
Код принимает только GCC. Но следующий код по-прежнему не может быть скомпилирован GCC.
int main(){
const_cast<int&&>(int(0));
}
Я не знаю, в чем разница, когда операндом является 0, int{0} и int(0) соответственно. На мой взгляд, все они prvalue типа int.
typedef int *A[3];
typedef const int *const CA[3];
int main(){
A &&r2 = const_cast<A&&>(CA{});
}
Этот код является формальным примером expr.const.cast # 3. К сожалению, он отклонен Clang.
Не знаю, можно ли это рассматривать как дефект стандарта или некорректную реализацию Clang? Я не знаю, какова цель третьего маркера [expr.const.cast # 4], почему в нем специально упоминается prvalue типа класса? (Намерено ли оно сказать, что будет применяться только prvalue типа класса временная материализация к нему? Однако это явно противоречит примеру для prvalue типа массива).