为Eigen和std::vector编写模板函数

Writing templated functions for Eigen and std::vectors

本文关键字:函数 vector Eigen std      更新时间:2023-10-16

我希望写一个模板函数来接受Eigen::VectorX* (float/int/double)和std::vector<*> (float/int/double)和"simple" int/float/double。

如何声明模板?下面的方法行不通。

// header.h
//std::vector function
template <typename T, typename A>
void do_something(std::vector<T, A> &stdvec)
{
    //do stuff with std::vector<T>
    //e.g. std::fill(stdvec.begin(),stdvec.end(),0);
}
//Eigen vector function
template <typename Derived>
void do_something(Eigen::EigenBase<Derived> &evec)
{
    //do stuff with Eigen::VectorX
    //e.g. evec.setZero()
}
//single value function
template <typename T>
void do_something(T &var)
{
    //do stuff with int/float/double
    //e.g. var = 0;
}

基本原理是不要为所有不同的组合编写单独的函数

您可以使用std::enable_if仅为算术类型启用完全泛型版本:

template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value,void>::type
do_something(T &var) { ... }

Eigen::VectorX*仅继承Eigen::EigenBase<Derived>,因此c++将优先使用do_something(T &var)方法。您可以将函数的特征变体声明为:

template<typename Scalar>
void do_something(Eigen::Matrix<Scalar, Eigen::Dynamic, 1> &evec) { /*...*/}

技巧不是编写几个函数(正如您所发现的),而是根据容器不同地应用标量函数(void do_something(T &var)):

标量:

do_something(var);

std::vector

std::transform(v.begin(), v.end(), v.begin(), do_something);

特征

matrix.unaryExpr(do_something);