【问题标题】:C++ Eigen Vector infer vector size at compile time for classC++ Eigen Vector 在类的编译时推断向量大小
【发布时间】:2021-05-06 21:31:10
【问题描述】:

我正在尝试为 Eigen::Matrix 创建一个包装类。它应该接收一个指向静态大小特征向量(1 行矩阵)的指针,并且应该在调用 getValue() 函数时返回一个副本。这是我目前拥有的

template<std::size_t N>
class InputV
{
public:

    InputV(const Eigen::Matrix<double, N, 1>* in) : in_(in)
    {

    }

    Eigen::Matrix<double, N, 1>
    getValue() const
    {
        return *in_;
    }

private:
    const Eigen::Matrix<double, N, 1>* in_;
};

TEST_CASE("dummy")
{
    Eigen::Matrix<double, 10, 1> a;
    
    InputV<10> in(&a);
}

但是,我需要两次明确地告诉它大小,一次是在源指针初始化期间,另一次是在创建 InputV 包装类时。有没有办法让 InputV 推断大小 N,所以我不必指定两次?

谢谢!

【问题讨论】:

  • decltype(in_) ?
  • 嗯,我不熟悉那个说明符。我正在看它,但你能解释一下我如何使用它来提供帮助吗?谢谢!
  • 您可以将 ctor 替换为 InputV(decltype(in_) in) : in_(in) {},但是您的属性 in_ 必须在 ctor 之前声明(即在您的类定义中更高)。
  • 嗯,我不知道 decltype 可以做到这一点,看起来很整洁,谢谢!
  • 我相当肯定decltype(in_) 将返回Eigen::Matrix&lt;double, 10, 1&gt; const * &amp;,这可能不是您想要的。

标签: c++ templates eigen


【解决方案1】:

如果您使用的是 C++17,则可以使用 class template argument deduction(和演绎指南,但在这种情况下您不需要它们):

Eigen::Matrix<double, 10, 1> a;

auto x = InputV(&a);
InputV y(&a);

如果您使用的是较旧的 C++ 版本(即 C++11 或 C++14),则可以使用辅助函数。这是因为函数可以在所有 C++ 版本中推导出模板参数:

template <std::size_t N>
InputV<N> makeInputV (Eigen::Matrix<double, N, 1> const * m) {
  return InputV<N>(m);
}

Eigen::Matrix<double, 10, 1> a;
auto x = makeInputV(&a);

现场示例:https://godbolt.org/z/GqT936

编辑:有点讨厌:如果将nullptr 作为参数传递给您的课程没有意义,那么就不要允许它。 InputV 构造函数的签名告诉我传入Eigen::Matrix 是可选的,传入nullptr 非常好。

如果不是这样,请使您的代码必须传入:InputV (Eigen::Matrix&lt;double, N, 1&gt; const &amp;)。 IE。使用引用而不是指针。

差得多的解决方案是记录您不应该传入nullptr(并保持文档是最新的,并确保使用代码的人阅读它,并且......)。但为什么一开始就允许它发生呢?

大吵大闹:)。

【讨论】:

  • 啊啊,真好,没想到用auto这么好,谢谢!
  • 是的,auto 是你的朋友。好吧,这是我的,我相信有些人会不同意:)。这有点主观。如果您想阅读一些意见,我建议您搜索“几乎总是自动”,您会找到很多文章。
  • 我大体上同意,但想说 a) 当涉及表达式模板时,您需要小心 auto(例如,auto x = 2*a; 实际上不会评估任何内容)。 b) 当以const &amp; 传递时,您有时必须注意不要存储提前超出范围的临时地址。
  • 是的,auto 和表达式模板的问题实际上已明确讨论过in the Eigen documentation。关于超出范围的const &amp; 参数,您始终可以创建一个InputV (Eigen::Matrix&lt;...&gt; &amp;&amp;) = delete 构造函数。这为您提供了一个非常简单的解决方案。
猜你喜欢
  • 2011-10-24
  • 2020-04-17
  • 1970-01-01
  • 2014-02-22
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多