【发布时间】:2017-01-06 00:12:25
【问题描述】:
GCC 和 Clang 都拒绝以下代码中的 C 样式转换。
http://coliru.stacked-crooked.com/a/c6fb8797d9d96a27
struct S {
typedef const int* P;
operator P() { return nullptr; }
};
int main() {
int* p1 = const_cast<int*>(static_cast<const int*>(S{}));
int* p2 = (int*)(S{});
}
main.cpp:在函数'int main()'中:
main.cpp:7:25:错误:从类型“S”到类型“int*”的无效转换
int* p2 = (int*)(S{});
main.cpp:7:15:错误:无法从类型“S”转换为指针类型“int *”
int* p2 = (int*)(S{});
^~~~~~~~~~~
但是,根据标准,C 样式转换可以执行由static_cast 后跟const_cast 执行的转换。这段代码格式正确吗?如果没有,为什么不呢?
【问题讨论】:
-
我一直在关注规范,现在试图弄清楚这一点。该规范非常不清楚它如何确定在尝试执行
static_cast和const_cast时使用的类型。如果它尝试按照您描述的方式执行它们,它绝对会起作用,但如果它尝试只执行const_cast<int*>(static_cast<int*>(S{}))),那么它肯定会失败。我不知道编译器如何知道尝试在此处添加const,但规范似乎没有说明任何关于该主题的内容... -
@templatetypedef 显然“static_cast 后跟 const_cast”的情况将在这两种情况下使用不同的类型,因为一种是 const 限定的,一种不是
-
@M.M 就是这样——规范实际上并没有说编译器应该尝试在任何地方添加
const。它只是说“先尝试static_cast,然后再尝试const_cast”,并没有说明如何选择static_cast使用的类型。 -
@Yakk 也许布赖恩的情况是无效的,因为
static_cast<int const *>后跟 const_cast 是可能的,但static_cast<int const * const>后跟 const_cast 也是可能的,因此它是模棱两可的。但我认为这表明标准措辞有缺陷,正如 templatetypedef 所暗示的那样 -
额外的 const 似乎毫无意义,但无论如何都可以将其转换为
const volatile,然后将const_cast两者都去掉。
标签: c++ language-lawyer