C++20 中严格的别名规则是否允许标准 c++ unicode 字符和下划线类型之间的“reinterpret_cast”?

2023-12-24

Do the C++20's 严格的别名规则 [基本.lval]/11 http://eel.is/c++draft/expr.prop#basic.lval-11任意允许以下...

  1. 之间投射char* and char8_t*
string str = "string";
u8string u8str { (char8_t*) &*str.data() }; // c++20 u8string

u8string u8str2 = u8"zß水????"
string str2 { (char*) u8str2.data() };
  1. 之间投射uint32_t*, uint_least32_t* and char32_t*
vector<uint32_t> ui32vec = { 0x007a, 0x00df, 0x6c34, 0x0001f34c };
u32string u32str { (char32_t*) &*ui32vec.data(), ui32vec.size() };

u32string u32str2 = U"zß水????"
vector<uint32_t> ui32vec2 { (uint32_t*) &*u32str2.begin(),
                            (uint32_t*) &*u32str2.end() };
  1. 之间投射uint16_t*, uint_least16_t* and char16_t*
vector<uint16_t> ui16vec = { 0x007a, 0x00df, 0x6c34, 0xd83c, 0xdf4c };
u16string u16str { (char16_t*) &*ui16vec.data(), ui16vec.size() };

u16string u16str2 = u"zß水\ud83c\udf4c"
vector<uint16_t> ui16vec2 { (uint16_t*) &*u16str2.begin(),
                            (uint16_t*) &*u16str2.end() };

Update

basic_string 构造函数过载 (6) https://en.cppreference.com/w/cpp/string/basic_string/basic_string

template< class InputIt >    
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );

向量构造函数过载 (4) https://en.cppreference.com/w/cpp/container/vector/vector

template< class InputIt >    
vector( InputIt first, InputIt last,
        const Allocator& alloc = Allocator() );

我想知道是否可以一起去遗留输入迭代器构造函数?...

  1. char* and char8_t* as 遗留输入迭代器
string str = "string";
u8string u8str {   str.begin(),   str.end()  };
u8string u8str { &*str.begin(), &*str.end()  };

u8string u8str2 = u8"zß水????"
string str2 {   u8str2.begin(),   u8str2.end() };
string str2 { &*u8str2.begin(), &*u8str2.end() };
  1. uint32_t*, uint_least32_t* and char32_t* as 遗留输入迭代器
vector<uint32_t> ui32vec = { 0x007a, 0x00df, 0x6c34, 0x0001f34c };
u32string u32str {   ui32vec.begin(),   ui32vec.end() };
u32string u32str { &*ui32vec.begin(), &*ui32vec.end() };

u32string u32str2 = U"zß水????"
vector<uint32_t> ui32vec2 { u32str2.begin(),
                            u32str2.end() };
vector<uint32_t> ui32vec2 { &*u32str2.begin(),
                            &*u32str2.end() };
  1. uint16_t*, uint_least16_t* and char16_t* as 遗留输入迭代器
vector<uint16_t> ui16vec = { 0x007a, 0x00df, 0x6c34, 0xd83c, 0xdf4c };
u16string u16str {   ui16vec.begin(),   ui16vec.end() };
u16string u16str { &*ui16vec.begin(), &*ui16vec.end() };

u16string u16str2 = u"zß水\ud83c\udf4c"
vector<uint16_t> ui16vec2 { u16str2.begin(),
                            u16str2.end() };
vector<uint16_t> ui16vec2 { &*u16str2.begin(),
                            &*u16str2.end() };

The char*_t类型行没有任何特殊的别名规则。因此,适用标准规则 https://timsong-cpp.github.io/cppwp/basic.lval#11。这些规则对于基础类型之间的转换没有例外。

所以你所做的大部分都是UB。不是 UB 的一种情况是char由于其特殊性。事实上你可以读取 a 的字节char8_t作为一个数组char。但你不能做相反的事情,读取 a 的字节char数组为char8_t.

现在,这些类型are完全可以互相转换。因此,您可以随时将这些数组中的值转换为其他类型。

话虽这么说,在真正的实现中,这些东西几乎肯定会起作用。好吧,直到他们不这样做,因为您试图通过不应该更改的事物来更改一件事,并且编译器不会重新加载更改后的值,因为它假设它无法更改。所以,实际上,只需使用正确的、有意义的类型即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++20 中严格的别名规则是否允许标准 c++ unicode 字符和下划线类型之间的“reinterpret_cast”? 的相关文章

随机推荐