int main(){
const_cast<int&&>(0);
}
据expr。康斯特。演员阵容#4
对于两种对象类型T1和T2,如果可以使用常量将指向T1的指针显式转换为类型“指向T2的指针”,则还可以进行以下转换:
如果操作数是glvalue,则引用const_转换的结果指的是原始对象,否则指的是应用临时物化转换的结果。
由于操作数0
是int类型的prvalue,指定的类型是int类型的右值引用。因此,在执行临时物化转换后,可以在此处应用第二个项目符号,该转换使原始操作数根据expr#basic成为glvalue。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)
时,我不知道这里有什么区别。在我看来,它们都是int类型的prvalue。
typedef int *A[3];
typedef const int *const CA[3];
int main(){
A &&r2 = const_cast<A&&>(CA{});
}
此代码是expr的正式示例。康斯特。演员阵容#3。不幸的是,它被叮当声拒绝了。
我不知道这是否会被认为是标准的缺陷,还是Clang的错误实现?我不知道[expr.const.cast#4]的第三个项目的意图是什么,为什么它特别提到类类型的prvalue?(它是否打算说只有类类型的prvalue才会被临时物化?然而,它显然与数组类型的prvalue的示例相矛盾)。
这里的关键是T1是否是类类型。类型int
不是类类型,因此4.3不适用。如果您使用的是std::string
,那么它可以:
const std::string && x = const_cast<std::string&&>(std::string("foo") + "bar");