微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在没有未定义行为的情况下重新解释或转换具有已知内存布局的对象

如何解决如何在没有未定义行为的情况下重新解释或转换具有已知内存布局的对象

我有一个带有 transposedView() 方法的矩阵类,我多年来一直使用它作为行向量和列向量之间的“零开销”转换。

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,T>*>(this);
    }
}

我曾经相信这一点,因为mat<1,N>的内存布局与mat<N,1>完全对应,但我have just learned认为该函数具有未定义的行为。你对我可以用什么来替换这个函数内容/实现有什么建议吗?

解决方法

你可以设计一个新的视图类模板,比如std::string_view对应std::string,或者Eigen::Map对应Eigen::Matrix(所以你看,这是一个常见的设计在 C++ 中)。视图类模板可以简单地持有一个指向它所查看的序列开头的指针和一个大小(如果您只想支持整个矩阵的视图,您可以省略 size 成员,因为它可以从其模板参数中推断出来)。您的 transposedView 函数可以返回这样的视图类。

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,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};
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。