c++ 在不违反“严格别名”的情况下使用std::array&分配C样式数组的子部分,从而调用UB?

k4ymrczo  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(128)

我可以使用std::array<int, N>来别名int[]的一部分而不调用UB吗?
https://en.cppreference.com/w/cpp/container/array“此容器是聚合类型,其语义与将C样式数组T[N]作为其唯一非静态数据成员的结构相同。”
动机:下面的copy函数不受我的控制,需要通过引用进行单次赋值,只有像std::array<int, N>这样的struct { int[N]; }才能进行这种“多对象赋值”?
这是UB吗?
有别的办法吗?

#include <iostream>
#include <array>

template <std::size_t N>
void print(int (&arr)[N], std::size_t number_rows, std::size_t number_cols) {
    assert(number_rows * number_cols == N);
    for (std::size_t r = 0; r != number_rows; ++r) {
        for (std::size_t c = 0; c != number_cols; ++c) {
            std::cout << arr[r * number_cols + c] << ' ';
        }
        std::cout << '\n';
    }
    std::cout << '\n';
}

void copy(std::array<int, 4>& a, std::array<int, 4>& b) {
  b = a;
}

int main() {

    int vals[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};

    print(vals, 4, 4);

    auto s1 = reinterpret_cast<std::array<int, 4>*>(&vals[0]);
    auto s2 = reinterpret_cast<std::array<int, 4>*>(&vals[4]);

    copy(*s2, *s1);

    print(vals, 4, 4);

}

产出

5tmbdcev

5tmbdcev1#

我可以使用std::array〈int,N〉来为int []的一部分取别名而不调用UB吗?
没有。
这是UB吗?
是的。
有别的办法吗?
这取决于您可以更改方案的哪些部分。
下面的copy函数不在我的控制之下
最简单的解决方案是不使用copy函数,因为它对您的用例没有用处。
std::array<int, N>&是原始int[]上的定制迭代器的operator*()的返回值
似乎没有好的方法来实现这样的operator*()
这似乎是一个很好的机会来定义一个定制的范围适配器,它带有可以从定制迭代器返回的定制赋值运算符。

相关问题