检查类型是否为特征 3 类型
Check if type is Eigen3 type
Eigen3 和内置类型的相互兼容性
大家好。我遇到了编写可以处理 Eigen3 类型(矩阵和数组(和内置类型的例程的问题。我可以用一个例子来最好地解释这一点:假设我有一个Meter<Type>
模板类,它能够在运行时收集统计信息。
Type 类应支持以下运算符:
-
operator=(Scalar)
-
operator=(Type)
-
operator+(Type)
-
operator-(Type)
-
operator*(Type)
-
operator/(Type)
-
operator*(Scalar)
-
operator/(Scalar)
Eigen3
类型为所有这些运算符提供了两个例外:首先,如果Type
是Eigen::MatrixBase
的某个子类,则operator*(Type)
表示点预管,如果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
结构在这种情况下不起作用,即使我已经使用过它并在其他类上测试了它而没有问题。
我需要在其他几个类中使用此行为,我不想明确地专门化它们中的每一个!有人知道我应该怎么做才能解决这个问题吗?
提前感谢任何帮助!
你的问题是你的特征is_scalar
它只接受基类而不是派生类。
您可以尝试以下操作:
namespace Helper
{
template <typename T> std::false_type is_scalar(const Eigen::MatrixBase<T>*);
template <typename T> std::false_type is_scalar(const Eigen::ArrayBase<T>*);
std::true_type is_scalar(...);
}
template<typename T>
struct is_scalar : decltype(Helper::is_scalar(std::declval<T*>()))
{};
我计算了同样的问题,并试图用C++17来解决它。这是我的解决方案。
template<typename Derived>
constexpr bool is_eigen_type_f(const EigenBase<Derived> *) {
return true;
}
constexpr bool is_eigen_type_f(const void *) {
return false;
}
template<typename T>
constexpr bool is_eigen_type = is_eigen_type_f(reinterpret_cast<T *>(NULL));
@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
的源代码,我还注意到,只要它提供一个类型 Scalar
- 算术类型 OR
- 成员指针或
- 指针或
- 空指针或
- 枚举常量
我说的对吗?
- 缺少类型说明符,显式类型为"缺少错误"
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- r语言 - C++ 类型为"const std ::?
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 错误:请求非类类型为"MULTIMEDIA_FILME [500]"的成员|
- 运行时错误:引用绑定到类型为"int"的空指针
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- 类型为 "Bucket&"(未限定的 const 限定)的引用不能使用 "SortedList." 类型的值进行初始化 如何修复此错误?
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 类型为 "int*" 的参数与 C++ 中错误类型"int**"参数不兼容
- 仅当类型为 std::complex 时,才进行缩放
- 类型为 'std::map< char,int > 的 <Swig 对象的代理
- 标量类型的特征模板无法编译固定大小的子矩阵操作
- 错误 C2679 二进制"<<":未找到采用类型为 'T' 的右侧操作数的运算符
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 特征稀疏矩阵的 CoeffRef 中的错误,元素类型为向量
- 为基本数据类型和特征数据类型编写模板函数
- 检查类型是否为特征 3 类型
- 对于类型修改特征,我是否应该为 typename::transform<...>::type 提供一个模板 typedef(又名使用)方便包装器?