【问题标题】:How to use C++ ranges to implement numpy.ndindex?如何使用 C++ 范围来实现 numpy.ndindex?
【发布时间】:2020-01-20 10:56:23
【问题描述】:

我想在 C++ 中实现 numpy.ndindex 的等价物。它应该为指定维度的多维数组生成索引。

这是二维数组的实现。

template <typename T>
inline auto NDIndex(T d0, T d1) {
  using namespace ranges;
  return views::cartesian_product(views::indices(d0), views::indices(d1));
}

// Usage
for (const auto[i1, i2] : NDIndex(5, 4)) {
  arr[i1][i2] = ...
}

我想在不牺牲性能的情况下将其推广到任意数量的维度。我可以在界面中使用大括号,例如NDIndex({5, 4})。我可以想到多种解决方案,但我不确定哪个会静态解决这个问题。

【问题讨论】:

    标签: c++ templates range-v3


    【解决方案1】:

    views::cartesian_product 已经是可变参数了,你只需要在其中展开一个包。

    template <typename... Ts>
    inline auto NDIndex(Ts ... ds) {
      using namespace ranges;
      return views::cartesian_product(views::indices(ds)...);
    }
    
    // Usage
    int main() {
        for (const auto[i1, i2] : NDIndex(5, 4)) {
        }
        for (const auto[i1, i2, i3] : NDIndex(5, 4, 7)) {
        }
    }
    

    【讨论】:

    • @bartop 哎呀,偷了你的例子而不改变它们:p
    • 顺便说一句,仍然无法编译:P
    【解决方案2】:

    这样就可以了

    #include <range/v3/view/indices.hpp>
    #include <range/v3/view/cartesian_product.hpp>
    
    
    template <unsigned... Ind>
    constexpr inline auto NDIndex() {
      using namespace ranges;
      return views::cartesian_product(views::indices(Ind)...);
    }
    
    
    int main() {
    
        for (const auto[i1, i2] : NDIndex<5, 4>()) {
        }
    
    
        for (const auto[i1, i2, i3] : NDIndex<5, 4, 7>()) {
        }
    }
    

    Live example

    【讨论】:

    • 我没有提到,但限制不能是 constexpr。我事先不认识他们。
    猜你喜欢
    • 2013-03-17
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多