代码之家  ›  专栏  ›  技术社区  ›  jkjkjk

带特征参数的模板推导

  •  2
  • jkjkjk  · 技术社区  · 6 年前
    template <typename Derived>
    void Fun(const std::vector<Eigen::MatrixBase<Derived>> &seqs);
    
    void Test() {
      std::vector<Eigen::MatrixXd> _seqs;
      Fun(_seqs);
    }
    

    由导师指导 functions taking eigen types ,则, Eigen::MatrixBase<Derived> 应接受 Eigen::MatrixXd 。但是,上述代码无法编译,错误消息为 mismatched types ‘Eigen::MatrixBase<Derived>’ and ‘Eigen::Matrix<double, -1, -1>’ 模板参数推断失败。

    那么,为什么会发生这种情况,我们应该如何应对?

    谢谢

    3 回复  |  直到 6 年前
        1
  •  3
  •   xskxzr    6 年前

    这是因为 the rule 那个 template-name<T> 整体参数 (忽略引用和cv限定符)可以从 D 如果 D 派生自 模板名称(<T> 对一些人来说 T 。此规则不适用于 std::vector<template-name<T>>

    即使您显式指定类型,因为没有从 std::vector<Derived> std::vector<Base> ,调用的格式仍然不正确。

    除了S.M.的解决方案,你还可以使用元编程。

    template <
        typename T,
        // enable only if T is derived from Eigen::MatrixBase<T>
        typename std::enable_if_t<std::is_base_of<Eigen::MatrixBase<T>, T>::value, int> = 0
    >
    void Fun(const std::vector<T>&);
    
        2
  •  1
  •   3CxEZiVlQ    6 年前

    您应该像下面这样声明函数和变量

    template <typename Derived>
    void Fun(const std::vector<std::unique_ptr<Eigen::MatrixBase<Derived>>> &seqs);
    
    std::vector<std::unique_ptr<Eigen::MatrixBase<Derived>>> _seqs;
    

    并用指向 Eigen::MatrixXd :

    _seq.emplace_back(new Eigen::MatrixXd);
    

    更新 @chtz告诉我 Eigen::MatrixBase (继承 struct EigenBase )没有虚拟析构函数。因此,我的上述解决方案是不正确的。剩下的唯一出路

    1. 使用 std::transform() 获取 std::vector<Eigen::MatrixBase<Derived>*> 从…起 std::vector<std::unique_ptr<Eigen::MatrixBase<Derived>>>
    2. @xskxzr提供的解决方案
        3
  •  1
  •   chtz    6 年前

    我不认为接受 vector 属于 Eigen::MatrixBase 对象。 我不知道您的用例,但通常只有存储实际的 Matrix 中的对象 矢量 。将其传递给模板化函数很容易:

    template<class S, int rows, int cols> 
    void func(std::vector<Eigen::Matrix<S, rows, cols> > const &) { }
    

    Usage example

    注意:您可以为具有默认值的模板参数添加更多模板参数,例如MatrixOptions或 矢量 。同样,您可以省略模板参数,例如,如果 S 始终是 double