【问题标题】:What's the right type for a join_rows() function?join_rows() 函数的正确类型是什么?
【发布时间】:2016-08-17 13:31:08
【问题描述】:

我写了一个函数joins the rows of two 2D arrays:

template <typename S, typename T>
Array<typename S::Scalar, Dynamic, Dynamic> join_rows(const ArrayBase<S> & A, const ArrayBase<T> & B) {
    Array<typename S::Scalar, Dynamic, Dynamic> C (A.rows(), A.cols()+B.cols());
    C << A, B;
    return C;
}

我想写一个更通用的函数,可以连接两个以上的数组。

它应该能够与任何可迭代容器一起使用,例如。 std::liststd::vector,所以我会使用模板模板参数。

我可以很容易地用两个 for 循环来纠正函数体,这不是问题,我只是在努力弄清楚这样一个函数的正确类型是什么。

(ps。我什至不确定我上面的代码是否有最好的类型,但它似乎可以完成这项工作)

【问题讨论】:

  • 您可以考虑使用一对迭代器,或者只是一个任意容器。我认为模板模板参数没有必要。
  • 你能有一个vector 的二维数组吗?不同的数组(可以)有不同的类型,对吧?
  • 您能否给出一些示例代码来说明如何调用此函数?
  • @IlyaPopov,如果我使用这对迭代器,我怎么知道我有多少列?
  • @user357269 您必须遍历整个序列并计数。不过,我不确定迭代器的类型是什么

标签: c++ eigen


【解决方案1】:

我不确定如何声明任意Arrays 的向量,但您可以实现一个函数模板,该模板将一个或多个直接传递给它的参数组合在一起。这通常是通过递归调用自身来完成的,处理每个连续的参数:

// end case (one argument): just forward the same array
template <typename T>
T&& join_rows(T&& A) {
    return std::forward<T>(A);
}

// main function template: two or more arguments
template <typename S, typename T, typename... R>
Array<typename S::Scalar, Dynamic, Dynamic> join_rows(const ArrayBase<S>& A,
                                                      const ArrayBase<T>& B,
                                                      const ArrayBase<R>&... rest) {
    Array<typename S::Scalar, Dynamic, Dynamic> C(A.rows(), A.cols()+B.cols());
    C << A, B;
    return join_rows(C, rest...); // call with the first two arguments combined
}

举例说明用法:

int main() {
    Array<int, 1, 3> arr1 = {1, 2, 3};
    Array<int, 1, 2> arr2 = {4, 5};
    Array<int, 1, 4> arr3 = {9, 8, 7, 6};

    cout << join_rows(arr1, arr2, arr3.reverse()) << endl; // 1 2 3 4 5 6 7 8 9

    return 0;
}

如果您想将单参数join_rows 限制为仅接受Eigen::Arrays,请添加std::enable_if 检查ArrayBase&lt;T&gt; 基类:

template <typename T>
std::enable_if_t<std::is_base_of<ArrayBase<std::decay_t<T>>,std::decay_t<T>>::value, T&&>
join_rows(T&& A) {
    return std::forward<T>(A);
}

对于大型Arrays,可能有更有效的方法来实现这一点。您可能会返回一个只会分配一个新的Array 对象的代理对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    相关资源
    最近更新 更多