提问者:小点点

它是应用于const_cast的操作数的临时物化转换吗


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

据expr。康斯特。演员阵容#4

对于两种对象类型T1和T2,如果可以使用常量将指向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));
}

当操作数分别为0int{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的示例相矛盾)。


共1个答案

匿名用户

这里的关键是T1是否是类类型。类型int不是类类型,因此4.3不适用。如果您使用的是std::string,那么它可以:

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