为了有效地编译时间大小的编译时大小的数组的子范围视图。
我一直在使用这种技术,因为我从来没有收到警告或错误,我认为没问题。
std::array<int,3> aa = {{1,2,3}};
std::array<int,2>& ee = reinterpret_cast<std::array<int,2>&>(aa[1]); // subrange {{2,3}}
assert(ee[0] == 2);
直到我找到这些评论https://stackoverflow.com/a/36046533/225186
我可以让gcc
用这个
int aaa = 5;
double& eee = reinterpret_cast<double&>(aaa);
或者
std::array<int,3> aaaa = 5;
std::array<double,2>& eeee = reinterpret_cast<std::array<double,2>&>(aaaa);
...但不是第一个代码块。
如果两个引用不完全在同一个地址中,似乎没有强制执行别名规则?
每个人似乎都同意这至少是UB。 这样可以吗?或者甚至是最糟糕的?
int aa[3] = {1,2,3};
int* ee = new(&aa[1]) int[2];
如果我可以说int ee[2] = new(&aa[1]) int[2];
,那将是完美的,因为ee
的类型将带有新的大小,我可以递归地使用子视图。
我可以使用std::basic_string_view<int>
吗?
在cppreference,唯一的限制是int
必须是char
- 就像。
(我认为是这样。)
答案 0 :(得分:1)
std::array<int,3> aa = {{1,2,3}};
std::array<int,2>& ee = reinterpret_cast<std::array<int,2>&>(aa[1]);
此绝对会破坏严格的别名规则,对ee
的访问权限为未定义的行为。
请参阅cppreference/reinterpret_cast/type aliasing:
...但不是第一段代码。
如果您的编译器没有产生警告,那么它并不意味着一切正常 - 标准不强制要求警告。编译器尽可能地提供帮助,但它们不会检测到所有标准违规行为。