Using enable_if, in class template method, to check if two function arguments arguments are both std::array or both std::vector

Pana

I am not a professional coder and I apologise if my question seams naive or malformed.

I am trying to have a class member function take std::array or std::vector in the arguments. Specifically I am passing two arguments that should either both be std::array or both be std::vector.

BEFORE trying to make the above work, a minimum set up of what I had was working only with std::vector arguments. a minimum set up is as follows, where v and p are the ones I desire to have passed as vectors or arrays:

// original version

class my_class_A{
// stuf
};

class my_class_B{
// other stuf
};

class I_am_a_class_of_methods{
public:
  inline void my_method(const std::vector<my_class_A> &v,
                        const std::vector<std::array<uint64_t,2> > &p,
                        const my_class_B &x,
                        my_class_B &y){
    // `v` and `p` are used to modify `x` and store the result in `y`
    return;
  }; 
};

I understand I could do what I want with function overloading, however, I decided I wanted to achieve the desired result with templates and std::enable_if, to force me to learn a bit more about them. Well I did learn a lot I didn't know... but not enough it seams. I have basically tried setting up a trait is_both_array_or_vector, and std::enable_if will check to see if the template call matches the trait. The final thing I tried is the following, which did compile, but it will only work for std::vector:

// current version

class my_class_A{
// stuf
};

class my_class_B{
// other stuf
};

// set up a type trait to check if both are vector or both are array
template <typename T1, typename T2>                                                                                                                                                                         
struct is_both_array_or_vector{                                                                                                                                                                             
  enum { value = false };                                                                                                                                                                                   
};                                                                                                                                                                                                          

template <typename T1, typename T2, typename A1, typename A2 >                                                                                                                                              
struct is_both_array_or_vector<std::vector<T1, A1>, std::vector<T2, A2> > {                                                                                                                                 
  enum { value = true };                                                                                                                                                                                    
};                                                                                                                                                                                                          

template <typename T1, typename T2, size_t D>                                                                                                                                                               
struct is_both_array_or_vector<std::array<T1, D>, std::array<T2, D> > {                                                                                                                                     
  enum { value = true };                                                                                                                                                                                    
}; 

// conditionally compile with enable_if
class I_am_a_class_of_methods{
public:
  template<template<typename,typename> U, template<typename,typename> S,
           typename Au, typename As> 
  typename std::enable_if<is_both_array_or_vector<U<my_class_A, Au>, S<std::array<uint64_t,2>,As> >::value >::type
  my_method(const U<my_class_A, Au> &v,
            const S<std::array<uint64_t,2>, As> &p,
            const my_class_B &x,
            my_class_B &y){
    // `v` and `p` are used to modify `x` and store the result in `y`
    return;
  }; 
};

When I compile with std::vector call from main everything works fine. This (of course) doesn't compile with std::array call (compiler of course complains).

If only I could make template arguments As and Au be able to be interpreted as size_t, then the template would find a match with an std::array call. This doesn't seam possible however, since I can have either typename or size_t, not both as far as I know. Thus my question is, how would I get enable_if to work in this circumstance?

0x499602D2

Update: As Javier said, you can keep a private function template that will handle the general case, and overload two methods for the types you want and pass them to that template.

class I_am_a_class_of_methods {
private:
  template <typename C1, typename C2>
  void my_method_priv(const C1& v, const C2& p, const my_class_B& x, my_class_B& y) {
    // ...
  }

 public:
  void my_method(const std::vector<my_class_A>& v,
                 const std::vector<array<uint64_t, 2>>& p,
                 const my_class_B& x,
                 my_class_B& y)
  { my_method_priv(v, p, x, y); }

  template <size_t N1, size_t N2>
  void my_method(const std::array<my_class_A, N1>& v,
                 const std::array<std::array<uint64_t, 2>, N2>& p,
                 const my_class_B& x,
                 my_class_B& y)
  { my_method_priv(v, p, x, y); }
};

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Check two arguments in Java, either both not null or both null elegantly

How do I enable_if a class with variadic template arguments?

"unpack" std::array<T,N> as arguments to function

Template specialization with std::enable_if<>

Overload operator for both std::vector and std::list

using replace logic in both arguments

A function template that accepts both std::vector and QVector?

Template class specialization with std::enable_if and a concrete type

std::function with templated arguments

A template method to take both const and non-const arguments

Using std::async and pass arguments in a vector to a function and gather results

Creating a method that accepts both Vector2 and Vector3 arguments in C#

Class template with array or vector arguments

Using std::enable if for template with 3 generic arguments

Using std::enable_if on template function return type to exploit SFINAE - compilation error

Mimic std::function template arguments

check function passed to template has class in arguments

C++ enable_if template class method if it is std::vector<std::vector<Type>>

std::function to variadic member function and then bind variadic template arguments

c++ class constructor template with std::enable_if and std::decay

Overloading a function with std::enable_if to avoid template substitution error

How can I implement a class template function with a std::enable_if metafunction?

std::list and std::vector - Best of both worlds?

How to define a template function with the help of std::enable_if

Call variadic templated function with arguments from a std::vector

std::array member in template class vs vector

C++ template function to concatenate both std::vector and std::array types

Passing both 2D array and vector of vectors to the template function

std::enable_if for std::is_integral and its negation both show as ambiguous candidate overloads