我有一个带有 transposedView()
的矩阵类我多年来一直使用的方法作为行 vector 和列 vector 之间的“零开销”转换。
template<int M, int N=M, typename T = double>
struct mat {
std::array<T,M*N> buf;
// ...
template<int Md = M, int Nd = N, typename = std::enable_if_t<Md == 1 || Nd == 1>>
const mat<N, M, T>& transposedView() const {
static_assert(M == 1 || N == 1, "transposedView() supports only vectors, not general matrices.");
return *reinterpret_cast<const mat<N, M, T>*>(this);
}
}
我曾经相信这一点,因为 mat<1,N>
的内存布局完全对应于 mat<N,1>
,但我have just learned该函数具有未定义的行为。您对我可以用什么替换此功能的内容/实现有什么建议吗?
最佳答案
你可以设计一个新的 View 类模板,比如std::string_view
对应于std::string
,或Eigen::Map
对应于Eigen::Matrix
(可见,这是C++中常见的设计)。 View 类模板可以简单地保存一个指向它查看的序列开头的指针和一个大小(如果你只想支持整个矩阵的 View ,你可以省略 size 成员,因为它可以从它的模板参数中推断出来).您的 transposedView
函数可以返回这样的 View 类。
template<int M, int N=M, typename T = double>
struct mat_view {
T *begin;
std::size_t size;
// member functions you want to support
// ...
}
template<int M, int N=M, typename T = double>
struct mat {
std::array<T,M*N> buf;
// ...
template<int Md = M, int Nd = N, typename = std::enable_if_t<Md == 1 || Nd == 1>>
const mat_view<N, M, T> transposedView() const {
static_assert(M == 1 || N == 1, "transposedView() supports only vectors, not general matrices.");
return {std::begin(buf), M * N};
}
}
关于c++ - 如何在不获取未定义行为的情况下重新解释或转换具有已知内存布局的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68569078/