C++ 检查类型是否为特征3类型 Eigen3和内置型互兼容性
大家好。我一直忙于编写既能处理特征3类型(矩阵和数组)又能处理内置类型的例程。我可以用一个例子来最好地解释这一点:假设我有一个C++ 检查类型是否为特征3类型 Eigen3和内置型互兼容性,c++,templates,eigen3,C++,Templates,Eigen3,大家好。我一直忙于编写既能处理特征3类型(矩阵和数组)又能处理内置类型的例程。我可以用一个例子来最好地解释这一点:假设我有一个Meter模板类,它能够在运行时收集统计数据 Type类应支持以下运算符: 运算符=(标量) 运算符=(类型) operator+(类型) 运算符-(类型) 运算符*(类型) 运算符/(类型) 运算符*(标量) 运算符/(标量) Eigen3types为所有这些运算符提供了两个例外:首先,如果Type是Eigen::MatrixBase的某个子类,则运算符*(Type
Meter
模板类,它能够在运行时收集统计数据
Type类应支持以下运算符:
运算符=(标量)
运算符=(类型)
operator+(类型)
运算符-(类型)
运算符*(类型)
运算符/(类型)
运算符*(标量)
运算符/(标量)
Eigen3
types为所有这些运算符提供了两个例外:首先,如果Type
是Eigen::MatrixBase
的某个子类,则运算符*(Type)
表示点积;如果Type
是Eigen::ArrayBase
的某个子类,则表示系数积。我可以很容易地解决这个问题;其次,两者都没有实现确保正确初始化为零所需的运算符=(标量)
我尝试实现以下函子类来帮助我处理这一区别,但我无法让它们工作:
用于处理内置类型和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;
};
表示0
不能隐式转换为Eigen::Matrix
,这意味着它选择了函子的set\u const\u impl
版本(其中两个参数共享一个公共类型Scalar
)。这也意味着我的is_scalar
构造在这种情况下不起作用,即使我已经使用了它,并且在其他类上测试过它,也没有问题
我在其他几个类中需要这种行为,我不想显式地专门化它们中的每一个!有人知道我该怎么做才能解决这个问题吗
提前感谢您的帮助 你的问题在于你的traits
是标量的,它只接受基类而不接受派生类
您可以尝试以下方法:
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*>()))
{};
名称空间帮助器
{
模板std::false_类型为_标量(常数特征::矩阵基*);
模板std::false_类型是_标量(const-Eigen::ArrayBase*);
std::true_类型是_标量(…);
}
模板
结构是标量:decltype(Helper::是标量(std::declval())
{};
@Jarod42
谢谢,您的建议带来了一些启发,但我发现了另一个我认为非常可靠的选项:我在命名空间std::\uu 1
中发现了is\u scalar
的实现。现在我的代码是
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;
};
templatestruct is\u scalar;
模板<类类型>
结构是\u标量:真\u类型{
使用标量=类型;
};
模板<类类型>
结构是\u标量:false\u类型{
使用Scalar=typename Type::Scalar;
};
我能够正确地区分内置类型和固有类型!无论如何谢谢你
编辑:
通过查看std::uu 1::is_scalar
的源代码,我还注意到该解决方案可能代表任何类型的容器对象,只要它提供一个
- 算术类型或
- 成员指针或指针
- 指针
- 空指针或
- 枚举常数
我说的对吗?我遇到了同样的问题,并试图用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));
模板
constexpr bool是特征型(const-EigenBase*){
返回true;
}
constexpr bool是特征型(const void*){
返回false;
}
模板
constexpr bool is_eigen_type=is_eigen_type_f(重新解释强制转换(NULL));
我强烈建议不要直接使用std::\u 1名称空间中的任何内容。它是特定于libc++的,不打算直接使用。
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*>()))
{};
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;
};
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));