如何编写一个既包含基本数据类型(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,那么这就是我所需要的。
答案 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 */
}
那样,它全都在一个函数中,我发现语法更加清晰。