c++ - 转置模板参数包

标签 c++ templates c++14 variadic-templates

我想将行优先参数列表传递给 constexpr 构造函数,并将数据存储在列优先数组中。我必须将模板参数包从行优先转换为列优先,我想出的唯一方法是使用这样的临时数组:

template <typename T, std::size_t rows, std::size_t cols = rows>
class Matrix final
{
public:
  std::array<T, cols * rows> m; // column-major matrix

  template <typename ...A>
  constexpr Matrix(const A... args) noexcept:
    m{transpose(std::array<T, rows * cols>{args...}, std::make_index_sequence<rows * cols>{})}
  {}

  template <std::size_t ...i>
  constexpr auto transpose(const std::array<T, cols * rows> a,
                           const std::index_sequence<i...>) noexcept
  {
    return std::array<T, cols * rows>{a[((i % rows) * cols + i / rows)]...};
  }
};

我想没有其他方法可以乱序访问参数包中的元素,但也许有一种方法可以在没有中间数组的情况下做到这一点。

最佳答案

要在不删除功能的情况下显着提高调试构建的性能,您需要将 std::array 替换为更基本的无功能版本:

https://quick-bench.com/q/FS2cphByJEWMFMsquI_Yor8ZnyI

生成的版本 (ChangedArrayBasic) 比 Clang 12.0、-O0、libstdc++ 上的原始版本快约 2.8 倍。

不得使用索引运算符,因为它在实践中似乎很大程度上无法优化,而是需要手动访问内部数组。

template <class T, size_t N>
struct BasicCustomArray
{
  T d[N];
};

template <typename T, std::size_t rows, std::size_t cols = rows>
class NewMatrixBasic final
{
public:
  using Arr = BasicCustomArray<T, cols * rows>; // <-----------------------------
  Arr m; // column-major matrix

  template <typename ...A>
  constexpr NewMatrixBasic(const A... args) noexcept:
    m{transpose(Arr{args...}, std::make_index_sequence<rows * cols>{})}
  {}

  template <std::size_t ...i>
  constexpr auto transpose(const Arr a,
                           const std::index_sequence<i...>) noexcept
  {
    return Arr{a.d[((i % rows) * cols + i / rows)]...}; // <---------------------
  }
};

关于c++ - 转置模板参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69881904/

相关文章:

c++ - c++中多项式的乘法

c++ - 如何在类模板的成员函数中正确调用函数对象?正在生成 Visual Studio 编译器错误 C2440

c++ - 重载 = 运算符和名称隐藏

c++ - 类型列表访问者模式示例

c++ - 模板类的模板函数特化

c++ - 为什么 decltype(auto) 不能按预期工作?

c++ - 我可以将外部 dll 添加到 npapi 插件吗,它应该安装在浏览器中?

c++ - 带有大量 SC_THREAD 的 Accellera SystemC 错误

c++ - 将毫秒转换为小时 :minutes:seconds:milliseconds in C++

Python - 根据提供的模式生成文件名