专门针对特征类型的函数

时间:2017-03-15 10:01:13

标签: c++ eigen

我正在编写一个模板化的稀疏容器类,并希望检查传入的数据是否等于零。数据类型将是整数或固定大小的特征类型。

#include <Eigen/Core>

template<typename T>
struct SparseContainer
{
    void insert(const T& value)
    {
        if(isZero(value))
            return;
        // ...
    }
};

int main(int argc, char* argv[])
{
    SparseContainer<int> a;
    a.insert(1);

    SparseContainer<Eigen::Vector2i> b;
    b.insert(Eigen::Vector2i(1, 0));
}

如何提供isZero()函数,以便它默认使用整数和特征类型,并且可以由类的用户为自己的类型进行扩展。我不使用boost,但是C ++ 11(即std::enable_if)没问题。

1 个答案:

答案 0 :(得分:1)

基于https://stackoverflow.com/a/22726414/6870253

#include <Eigen/Core>
#include <iostream>
#include <type_traits>

namespace is_eigen_detail {
    // These functions are never defined.
    template <typename T>
    std::true_type test(const Eigen::EigenBase<T>*);
    std::false_type test(...);
}

template <typename T>
struct is_eigen_type : public decltype(is_eigen_detail::test(std::declval<T*>()))
{};

template<class T>
typename std::enable_if<is_eigen_type<T>::value, bool>::type isZero(const T& x) { return x.isZero(); }

template<class T>
typename std::enable_if<!is_eigen_type<T>::value, bool>::type isZero(const T& x) { return x == 0; }

int main()
{
    Eigen::Vector3d a;
    Eigen::Array3d b;

    a.setZero();
    b.setRandom();

    std::cout << "a: " << isZero(a) << "\nb: " << isZero(b) << "\n0.0: " << isZero(0.0) << std::endl;
}

N.B。:当然,如果你只想专门研究矩阵或矩阵和数组,你可以使用Eigen::MatrixBaseEigen::DenseBase代替Eigen::EigenBase