Template function using the std :: vector or std :: array

I have a function that currently accepts 2 vectors that can contain any simple old data ...

template <class T> void addData(const vector<T>& yData, vector<T> xData) { .. } 

Question:

  • Is it possible to change it to take two std::array or two std::vector , or even a combination of them, given that these containers use a different number of template arguments?
+6
source share
3 answers

Why not just use this, which works with any container using random access iterators, including plain old arrays. If you can use iteration instead of indexing, you can also opt out of the random access requirement.

 template <typename Cnt1, typename Cnt2> void addData(const Cnt1& yData, Cnt2 xData) // is pass-by-value intended? { using std::begin; using std::end; typedef decltype(*begin(yData)) T; const auto sizeY = end(yData) - begin(yData); const auto sizeX = end(xData) - begin(xData); // ... } 

C ++ 03 version (does not support plain old arrays):

 template <typename Cnt1, typename Cnt2> void addData(const Cnt1& yData, Cnt2 xData) // is pass-by-value intended? { typedef Cnt1::value_type T; const size_t sizeY = yData.end() - yData.begin(); const size_t sizeX = xData.end() - xData.begin(); // ... } 
+6
source

Of course, it is simply a matter of creating a suitable character trait. The example simply uses the f() function with one argument, but it is trivial to expand to accept any number of arguments.

 #include <array> #include <vector> #include <deque> #include <utility> #include <cstddef> template <typename T> struct is_array_or_vector { enum { value = false }; }; template <typename T, typename A> struct is_array_or_vector<std::vector<T, A>> { enum { value = true }; }; template <typename T, std::size_t N> struct is_array_or_vector<std::array<T, N>> { enum { value = true }; }; template <typename T> typename std::enable_if<is_array_or_vector<T>::value>::type f(T const&) { } int main() { f(std::vector<int>()); // OK f(std::array<int, 17>()); // OK f(std::deque<int>()); // ERROR } 
+7
source

Alternative solution:

 #include <iostream> #include <vector> #include <array> using std::vector; using std::array; template <typename Container> struct container_helper; // undefined template <typename T> struct container_helper<vector<T>> { explicit container_helper(vector<T>& data) : _data(data) {} T* get_data() { return &_data[0]; } size_t get_size() { return _data.size(); } private: vector<T>& _data; }; template <typename T, size_t N> struct container_helper<array<T,N>> { explicit container_helper(array<T,N>& data) : _data(data) {} T* get_data() { return &_data[0]; } size_t get_size() { return N; } private: array<T,N>& _data; }; template <typename Container1, typename Container2> void add_data(Container1& c1, Container2& c2) { container_helper<Container1> c1_helper(c1); container_helper<Container2> c2_helper(c2); /* do whatever you want with the containers */ std::cout << "c1 size " << c1_helper.get_size() << std::endl; std::cout << "c2 size " << c2_helper.get_size() << std::endl; } int main() { vector<int > v_ints(3); array<int, 2> a_ints; add_data(v_ints, a_ints); } 
+1
source

All Articles