Tendo lido bastante sobre o propósito das uniões e trocadilhos de tipos (que basicamente não são permitidos e você deve confiar na otimização do compilador para eliminar chamadas memcpy), estou me perguntando se o seguinte uso de uma união é inseguro, ou se é um comportamento indefinido, ou se é, de fato, um uso perfeitamente compatível e seguro de uma união. A ideia é que os dados subjacentes sejam todos do mesmo tipo fundamental (int, double, etc.), mas eu só quero observar como eles são dispostos de maneiras diferentes ou nomeados de maneiras diferentes. Eu talvez chamaria isso de "trocadilho de contêiner" em vez de "trocadilho de tipos".
// main.cpp
// compile with `c++ main.cpp -std=c+23`
#include <iostream>
#include <array>
#include <format>
struct Mat2 {
union {
std::array<float, 4> data;
std::array<std::array<float, 2>, 2> rows;
struct { float x, y, z, w; };
};
};
int main() {
// sometimes you want to think about it in rows
Mat2 m{ .rows = {{ {0, 1},
{2, 3} }}};
for (auto &row : m.rows) {
for (auto &col : row) {
std::cout << col << " ";
}
std::cout << "\n";
}
// sometimes you want to think about it as a block of data
std::cout << "\n";
for (auto &d : m.data) {
std::cout << d << " ";
}
std::cout << "\n\n";
// sometimes you want to access elements based on sematic names
std::cout << std::format("{}, {}, {}, {}", m.x, m.y, m.z, m.w);
std::cout << std::endl;
}