std::可选与 Eigen::ArrayBase

问题描述 投票:0回答:1
template <typename Derived>
std::optional<Eigen::Array<typename Derived::Scalar, Eigen::Dynamic, Eigen::Dynamic>>
function1(const std::optional<Eigen::ArrayBase<Derived>>& opt1,
     const std::optional<Eigen::ArrayBase<Derived>>& opt2)
{

}

如何用 Eigen::ArrayBase 编写这种模板,使其可以接受两个 Array 或 Matrix 或 nullopt

喜欢:

ArrayXXd a(4, 3);
ArrayXXd b(4, 3);
auto q = function1(a,b);

我知道我能做到:

function2(const Eigen::ArrayBase<Derived1>& opt1,
          const Eigen::ArrayBase<Derived2>& opt2)
{
}
templates generics option-type eigen3
1个回答
0
投票

我建议不要这样做,但通过一些辅助函数可以使其工作。

#include <optional>
#include <functional>
// using std::cref, std::reference_wrapper

template<class Derived>
using optional_const_array_ref =
std::optional<std::reference_wrapper<const Eigen::ArrayBase<Derived>>>;

template<class Derived>
optional_const_array_ref<Derived>
make_optional_const_array(const Eigen::ArrayBase<Derived>& arr)
{ return std::cref(arr); }

template <typename Derived>
void function1(const optional_const_array<Derived>& opt1)
{
    if(opt1)
        std::cout << opt1->get().transpose() << '\n';
}

int main()
{
    Eigen::Array3d b(1., 2., 3.);
    function1(make_optional_const_array(b + 1.));
}

这很难的原因:

  • option
    按值包含其内容。你不能将它与抽象类一起使用
  • 你对类型推导规则期望过高
  • 我们创建了很容易成为悬空指针的东西。 C++ 在这方面非常不安全,但至少它的一部分是为了防止你这样做

几个注意事项:

  1. 不能使用
    option->
    访问里面的数组。您必须执行额外的步骤使用
    reference_wrapper::get()
  2. 在任何情况下都无法延长该
    option
    或其内容的生命周期。这一切似乎都是创建悬空指针的秘诀
  3. 空的
    optional
    应该具有什么派生类型?您必须定义 some 类型,但不一定要使用 Eigen 中的每种类型。其一,您创建了一个额外的模板实例化,这只会浪费大量编译后的代码大小。此外,您可能会触发静态断言和其他编译时问题,例如,如果标量类型与您期望的类型不同。您可能必须为每个调用站点显式定义类型。例如。
    function1(optional_const_array<Eigen::Array3d>{})

我是否已经提到过我认为这不是一个好主意?因为我认为这不是一个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.