shared_ptr数组特化版static_pointer_cast的合法性探讨
这个转换的合法性取决于所使用的C++版本,结合标准对指针转换和std::static_pointer_cast的定义分析如下:
核心规则回顾
根据标准定义,std::static_pointer_cast<T>(shared_ptr<U>) 的合法性要求对应的指针转换 static_cast<T*>((U*)nullptr) 必须合法,这与cppreference的描述一致。
C++17及更早版本
在C++17中,直接将未知边界数组指针转换为元素指针的static_cast是不合法的:
// C++17中编译失败 auto p3 = static_cast<int*>((int[]*)nullptr);
标准不允许将int[]*这类指向未知边界数组的指针,直接转换为int*指向单个元素的指针。按照std::static_pointer_cast的规则,此时std::static_pointer_cast<int>(std::shared_ptr<int[]>{}) 本应不合法,但主流编译器(GCC、Clang、MSVC)都允许了这个转换,属于编译器提供的非标准扩展行为。
C++20及以后版本
C++20标准调整了数组指针的转换规则:允许将指向未知边界数组的指针(如int[]*)通过static_cast转换为指向其元素类型的指针(如int*),此时对应的指针转换变为合法:
// C++20中编译通过 auto p3 = static_cast<int*>((int[]*)nullptr);
对应的,std::static_pointer_cast<int>(std::shared_ptr<int[]>{}) 也符合标准要求,编译器的支持属于合规行为。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

