大家好。我陷入了编写可以处理Eigen3类型(矩阵和数组)和内置类型的例程的问题。我可以用一个示例来最好地解释这一点:假设我有一个Meter<Type>
模板类,它能够在运行时收集统计信息。
Type类应支持以下运算符:
operator=(Scalar)
operator=(Type)
operator+(Type)
operator-(Type)
operator*(Type)
operator/(Type)
operator*(Scalar)
operator/(Scalar)
Eigen3
类型提供了所有这些运算符的有两个例外:首先,operator*(Type)
如果代表点preductType
是一些子类,Eigen::MatrixBase
并且表示系数之积,如果Type
是的一些亚类Eigen::ArrayBase
。我可以轻松解决此问题;第二,没有人实现operator=(Scalar)
确保正确初始化为零的要求。
我尝试实现以下仿函数类来帮助我处理区别,但是我无法使它们起作用:
处理内置类型和Eigen3
类型之间区别的一些结构:
template < class _Type > struct is_scalar : true_type {
using Scalar = _Type;
using Type = _Type;
static constexpr bool value = true;
};
template < class _Matrix >
struct is_scalar<Eigen::MatrixBase<_Matrix>> : false_type {
using Scalar = typename Matrix::Scalar;
static constexpr bool value = false;
};
template < class _Array >
struct is_scalar<Eigen::ArrayBase<_Array>> : false_type {
using Scalar = typename Array::Scalar;
static constexpr bool value = false;
};
函数实现本身
template < class Scalar, bool is_scalar = Math::is_scalar<Scalar>::value >
struct set_const_impl;
template < class Scalar >
struct set_const_impl< Scalar, true > {
static const void run(Scalar &_x, Scalar _y) noexcept { _x = _y; }
};
template < class EigenType >
struct set_const_impl<EigenType, false> {
template < class Scalar >
static const void run(Eigen::EigenBase<EigenType> &_x, Scalar _y) noexcept {
_x.derived().setConstant(_y);
}
};
template < class Type, class Scalar > void set_const(Type &_x, Scalar _y) noexcept {
set_const_impl<Type>::run(_x, _y);
}
template < class Type > void set_zero(Type &_x) noexcept {
set_const_impl<Type>::run(_x, 0);
}
专用版本set_const_impl<EigenType>
永远不会被实例化。例如,如果我打电话
Eigen::Matrix<double, 3, 1> m1;
set_zero(m1);
我让编译器0
在网上抱怨
set_const_impl<Type>::run(_x, 0);
表示0
不能隐式转换为Eigen::Matrix<double, 3, 1>
,这表示它选择set_const_impl<Scalar, true>
了函子的版本(两个参数共享一个公共类型Scalar
)。这也意味着is_scalar
即使在我已经使用过它并且在其他类上没有问题地对其进行过测试的情况下,我的构造也无法正常工作。
我在其他几个类中也需要这种行为,而我不想明确地专门化每个类!谁知道我该怎么做才能解决此问题?
在此先感谢您的帮助!
@ Jarod42
谢谢您的建议,但我发现了另一个我认为很确定的选择:我is_scalar<Type>
在命名空间中找到了一个实现std::__1
。现在我的代码读取
template < class Type, bool _is_scalar = std::__1::is_scalar<Type>::value > struct is_scalar;
template < class Type >
struct is_scalar<Type, true> : true_type {
using Scalar = Type;
};
template < class Type >
struct is_scalar<Type, false> : false_type {
using Scalar = typename Type::Scalar;
};
而且我能够正确区分内置类型和特征类型!不管怎样,谢谢你!
编辑:
通过查看std::__1::is_scalar
I的源代码,我还注意到,此解决方案可以代表任何类型的容器对象,只要它提供的类型Scalar
是
我对么?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句