2017-03-15 33 views
1

我正在編寫一個模板化的稀疏容器類,並希望檢查傳入數據是否等於零。數據類型將是整數或固定大小的特徵類型。爲本徵類型專門設計一個函數

#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

基於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,如果你只想專注於矩陣或矩陣和數組。

相關問題