微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决是否是应用于 const_cast 的操作数的临时物化转换

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

根据expr.const.cast#4

对于两个对象类型 T1 和 T2,如果可以使用 const_cast 将指向 T1 的指针显式转换为“指向 T2 的指针”类型,则还可以进行以下转换:

  • 可以使用强制转换 const_cast; 将 T1 类型的左值显式转换为 T2 类型的左值;
  • 可以使用强制转换 const_cast 将 T1 类型的泛左值显式转换为 T2 类型的 xvalue;和
  • 如果 T1 是类类型,则可以使用强制转换 const_cast 将 T1 类型的纯右值显式转换为 T2 类型的 xvalue。

如果操作数是泛左值,则引用 const_cast 的结果引用原始对象,否则引用应用临时物化转换的结果。

由于操作数 0 是 int 类型的纯右值,并且指定的类型是 int 类型的右值引用。因此,根据 expr#basic.lval-7

执行临时物化转换使原操作数成为泛左值之后,可以在此处应用第二个项目符号

每当纯右值作为期望该操作数的泛左值的运算符的操作数出现时,就会应用临时物化转换以将表达式转换为 xvalue。

然而,这个 snippet 被 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 类型的纯右值

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]第三个子弹的用意是什么,为什么特别提到类类型的纯右值?(是说只应用类类型的纯右值吗?临时物化它吗?但是,它显然与数组类型的纯右值的例子相矛盾)。

解决方法

这里的关键是如果 T1 是一个类类型。类型 int 不是类类型,因此 4.3 不适用。如果您使用 std::string,它会起作用:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。