c++ - 我可以将 std::array 转换为切片吗?或者还有什么我可以用的吗?

标签 c++ arrays stl c++11

这是未定义的行为吗?

std::array<int, 5> x = {3, 5, 1, 2, 3};
std::array<int, 3>& y = *reinterpret_cast<std::array<int, 3>*>(&x[1]);
for(int i = 0; i != 3; i++) {
    std::cout << y[i] << "\n";
}

也许是的,但我真的觉得应该有一种安全的方式来切片 std::arrays。

编辑按照 Radek 的建议:

template<unsigned N, unsigned start, unsigned end, typename T>
std::array<T, end - start>& array_slice(std::array<T, N>& x)
{
    static_assert(start <= end, "start <= end");
    static_assert(end <= N-1, "end <= N");
    return *reinterpret_cast<std::array<T, end - start>*>(&x[start]);
}

编辑: 好吧,我决定我对 std::array 不满意并且会转向其他东西,有什么想法吗?

最佳答案

是的,那是未定义的行为。您正在使用一种类型并且 reinterpret_cast把它传给另一个。事实上,使用 reinterpret_cast应该是“这里有龙!”的大红旗

至于切片数组,那是不会发生的。 std::array包含值;其中的一部分将包含对该数组的一部分的引用。因此,它不会是 std::array .您可以复制 数组切片,但不能使用 std::array .您需要使用 std::vector ,因为它允许调用构造函数,以及从一系列值进行构造。记住:std::array只是 C 风格数组的一个更好的包装器。

委员会正在研究模板 array_ref<T>类,这正是它所说的:对 T 类型数组的某个段的引用.这可能是一个常规的 C 风格数组,一个 std::vector , 一个 std::array ,或者只是用 new T[] 分配的一些内存.有some library implementations of the class already , 但还没有标准化。


Following Radek's suggestion:

在函数中隐藏未定义的行为不会使其成为定义的行为。您可以假装它不是未定义的,但它仍然是。在你使用那个 reinterpret_cast 的那一刻,你愿意放弃生活在 C++ 的土地上。

关于c++ - 我可以将 std::array 转换为切片吗?或者还有什么我可以用的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10760773/

相关文章:

c++ - 在 C++ 中将 SQL 查询返回到 vector<double> 中的函数

javascript - 在 Javascript/Lodash 中更新对象数组中的单个对象字段

java - 如何在方法中声明数组

c++ - 在 public const 方法中访问私有(private)成员

c++ - 播放 .wav 文件

c++ - 字符串和 const char* 和 .c_str()?

c++ - 在 C++ 中, 'Node' 是一个类, 'node' 是 'Node' 的实例。为什么 "*node = nullptr "是错误的,而 "*node = NULL"是正确的?

arrays - 计算列表中 k 个最大数字之和的有效方法?

c++ - 如何根据动态属性对项目进行排序?

c++ - std::map 或 std::list 的 mem_set