为基本数据类型和 Eigen 数据类型编写模板函数

Writing a template function for basic and Eigen data types

我如何编写一个同时接受基本数据类型(int、float、double 等)和 Eigen 库类型(Vector2f、Vector4d、Matrix4f 等)的函数?具体来说,我想要一个将提供的参数转换为 N 类型的转换函数。

例如:

float x1 = cast<float>(1);
double x2 = cast<double>(2.0);
Vector2d x3 = cast<double>(Vector2f(3.0f, 3.0f));
Vector2f x4 = cast<float>(Vector2i(4, 4));

简单的部分:

template<typename T, typename N>
N cast(const T& source) const
{
    return static_cast<N>(source);
}

转换特征类型:

template<typename T, typename N>
Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<typename Eigen::internal::traits<T>::Scalar, N>, const T> cast(const Eigen::MatrixBase<T>& source) const
{
    return source.cast<N>();
}

在 Eigen 中,从 Vector2f v 到 Vector2d 的转换是使用 v.cast<double>() 完成的,因此模板参数是标量的数据类型,而不是新类型本身。

我遇到的麻烦(至少我认为这是主要问题)是我不知道如何将这两个模板放在一起。 Eigen 可能应该是第一个的特化,但这有可能吗?模板本身编译,但例如cast<Vector2f, double>(Vector2f::Zero()) 不会,因为 'static_cast' :无法从 'const Eigen::Vector2f' 转换为 'double'.

怎么办?非常欢迎C++11解决方案,但请慢慢打字,因为我不是模板向导。

更新: 我需要这个的原因是我希望能够方便地将容器的内容 std::vector<T> 转换为 std::vector<N>,例如 std::vector<Vector2f>std::vector<Vector2d>,但也可以从 std::vector<float>std::vector<double>。为此,我遍历所有元素并使用所需的函数转换每个元素。因此,如果有更好的方法来转换 std::vector 的 Eigen 类型,这就是我所需要的。

您可以使用std::enable_if将通用版本限制为仅算术类型:

template<typename T, typename N>
typename std::enable_if<std::is_arithmetic<T>::value,N>::type
cast(const T& source) const {
  return static_cast<N>(source);
}

对于 C++17,还有另一种解决方案,我个人认为更优雅,使用 if constexpr:

template<typename T, typename N>
std::conditional<std::is_arithmetic<T>::value, N, /* your Eigen return type here */>::type
cast( const T& source ) {
    if constexpr( std::is_arithmetic<T>::value )
        return static_cast<N>(source);
    else
        /* Eigen cast */
}

这样一来,一切都在一个函数中,我发现语法更清晰一些。