Reputation: 45
I wish to write a templated function to accept both Eigen::VectorX* (float/int/double) and std::vector<*> (float/int/double) and "simple" int/float/double.
How do i declare the template? The following doesn't work.
// 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;
}
The rationale is to not write individual functions all the different combinations.
Upvotes: 1
Views: 670
Reputation: 29255
You can use std::enable_if
to enable the fully generic version for arithmetic types only:
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value,void>::type
do_something(T &var) { ... }
Upvotes: 1
Reputation: 553
The trick is not to write several functions (as you discovered), but to apply the scalar function (void do_something(T &var)
) differently depending on the container:
do_something(var);
std::vector
std::transform(v.begin(), v.end(), v.begin(), do_something);
matrix.unaryExpr(do_something);
Upvotes: 0
Reputation: 18827
Eigen::VectorX*
only inherits from Eigen::EigenBase<Derived>
, so C++ will prefer the do_something(T &var)
method. You can declare the Eigen variant of your function as:
template<typename Scalar>
void do_something(Eigen::Matrix<Scalar, Eigen::Dynamic, 1> &evec) { /*...*/}
Upvotes: 0