C++ C++;特征向量推断类在编译时的向量大小

C++ C++;特征向量推断类在编译时的向量大小,c++,templates,eigen,C++,Templates,Eigen,我正在尝试为Eigen::Matrix创建一个包装器类。它应该接收一个指向静态大小特征向量(一行矩阵)的指针,并在调用getValue()函数时返回一个副本。这就是我现在拥有的 template<std::size_t N> class InputV { public: InputV(const Eigen::Matrix<double, N, 1>* in) : in_(in) { } Eigen::Matrix<double

我正在尝试为Eigen::Matrix创建一个包装器类。它应该接收一个指向静态大小特征向量(一行矩阵)的指针,并在调用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(常数本征::矩阵*in):in(in)
{
}
本征矩阵
getValue()常量
{
返回*在u3;;
}
私人:
常数本征::矩阵*in;
};
测试用例(“假人”)
{
特征矩阵a;
输入(&a);
}
但是,我需要显式地告诉它两次大小,一次是在源指针初始化期间,另一次是在创建InputV包装类时。有没有办法让InputV推断出大小N,这样我就不必指定它两次了


谢谢

如果您使用的是C++17,您可以使用(和演绎指南,但在本例中不需要):

Eigen::矩阵a;
自动x=输入(&a);
输入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);
模板
InputV makeInputV(特征::矩阵常数*m){
返回输入v(m);
}
特征矩阵a;
自动x=makeInputV(&a);
实例:

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

如果不是这样的话,那么将代码设置为必须传入:
InputV(Eigen::Matrix const&)
。即使用引用而不是指针

差得多的解决方案是记录不应传入的
nullptr
(并保持文档的最新状态,确保使用代码的人都能阅读文档,以及……)。但为什么一开始就让它发生呢


咆哮:)。

decltype(in)
?嗯,我不熟悉那个说明符。我正在看,但是你能解释一下我如何使用它来帮助你吗?谢谢你可以用InputV(decltype(in){}替换这个ctor,但是你的属性
必须在这个ctor之前声明(例如,在你的类定义中是更高的)。嗯,我不知道decltype可以做到这一点,看起来真的很整洁,谢谢!我很确定,
decltype(in_u)
将返回
Eigen::Matrix const*&
,这可能不是您想要的。啊,这真是太好了,我没想到我能如此巧妙地使用auto,谢谢!是的,
auto
是你的朋友。嗯,这是我的,我相信有些人会不同意:)。这有点主观。如果你想阅读一些观点,我建议搜索“几乎总是自动的”,你会找到很多文章。我大体上同意,但我想说的是a)当涉及表达式模板时,你需要小心使用
auto
(例如,
auto x=2*a;
实际上不会评估任何内容)。和b)当作为
常量传递时&
,您有时必须注意,您没有存储提前超出范围的临时地址。是的,
auto
和表达式模板的问题实际上已经明确讨论过了。关于超出范围的
const&
参数,您始终可以创建
InputV(Eigen::Matrix&&)=delete
构造函数。这给了你一个非常简单的解决方案。
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);