c++ - Differentiate between 1D and 2D container in template class constructor (SFINAE) -


so, have class, has array of arrays private member. wish have 2 constructors each case (1d or 2d). of course declaration happens same, template deduction can't job without me doing it. here's code:

edit: need work stl containers vector or c++ array. why overcomplicating , not going "arrays" fix.

#include <iostream> #include <array>  template<class t, std::size_t rows_t, std::size_t cols_t> class test { private:     std::array<std::array<t, cols_t>, rows_t> _data; public:         auto begin() { return this->_data.begin(); }     auto end() { return this->_data.end(); }       //constructor     template<class type_t>     test(const type_t &arr)     {         std::size_t j = 0;         (const auto &num : arr)             this->_data[0][j++] = num;     }      template<class type_t>     test(const type_t &arr)     {         std::size_t = 0;         (const auto &el : arr)         {             std::size_t j = 0;             (const auto &num : el)                 this->_data[i][j++] = num;             ++i;         }     } };  int main() {     double arr[3] = { 1, 2, 3 };     double arr2[2][2] = { {1, 2}, {3, 4} };      test<double, 1, 3> obj = arr;      test<double, 2, 2> obj2 = arr2;      (const auto &i : obj2)     {         (const auto &j : i)             std::cout << j << " ";         std::cout << std::endl;     }      std::cin.get(); } 

note: i've been reading enable_if, don't quite understand how works. can done that?

first, have "teach" compiler what's 2d , what's not. hence, have define following type trait:

template<typename t> struct is2d : public std::false_type {}; template<typename t, std::size_t n, std::size_t m> struct is2d<std::array<std::array<t, m>, n>> : std::true_type {}; template<typename t> struct is2d<std::vector<std::vector<t>>> : std::true_type {}; template<typename t, std::size_t n, std::size_t m> struct is2d<t[n][m]> : std::true_type {}; 

then set class definition in following way:

template<class t, std::size_t rows_t, std::size_t cols_t> class test{   std::array<std::array<t, cols_t>, rows_t> _data;    template<class type_t>   std::enable_if_t<!is2d<type_t>::value, void>   test_init(type_t const &arr) {     std::size_t j = 0;     (const auto &num : arr) _data[0][j++] = num;   }    template<class type_t>   std::enable_if_t<is2d<type_t>::value, void>   test_init(type_t const &arr) {     std::size_t = 0;     for(const auto &el : arr) {       std::size_t j = 0;       (const auto &num : el) _data[i][j++] = num;       ++i;     }   }  public:    auto &operator[](const std::size_t &i) { return this->_data[i]; }   auto begin() { return this->_data.begin(); }   auto end() { return this->_data.end(); }    //constructor   template<class type_t> test(type_t const &arr) { test_init(arr); } }; 

live demo


Comments

Popular posts from this blog

matlab - error with cyclic autocorrelation function -

django - (fields.E300) Field defines a relation with model 'AbstractEmailUser' which is either not installed, or is abstract -

c# - What is a good .Net RefEdit control to use with ExcelDna? -