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

时间:2015-11-04 13:58:32

标签: c++ templates c++11 eigen eigen3

如何编写一个既包含基本数据类型(int,float,double,...)又包含特征库类型(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>()完成的,因此模板参数是标量的数据类型,而不是新类型本身。

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

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

更新 我需要这个的原因是我希望能够方便地将容器的内容std::vector<T>转换为std::vector<N>,例如std::vector<Vector2f>转换为std::vector<Vector2d>,同时也来自std::vector<float> {1}}到std::vector<double>。为此,我遍历所有元素并使用所需的函数转换每个元素。因此,如果有更好的方法来构建特征类型的std :: vector,那么这就是我所需要的。

2 个答案:

答案 0 :(得分:3)

您可以使用+---------+--------------+------------+ | account | ordered_qty | ROW_NUMBER | +---------+--------------+------------+ | ASDA | 15 | 1 | | ASDA | 12 | 2 | | ASDA | 10 | 3 | | TESCO | 15 | 1 | | TESCO | 12 | 2 | | TESCO | 10 | 3 | +---------+--------------+------------+ 将常规版本限制为算术类型:

std::enable_if

答案 1 :(得分:1)

对于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 */
}

那样,它全都在一个函数中,我发现语法更加清晰。