memC
memC

Reputation: 1025

looping over all arguments of a function in C++

I want to do identical processing to a bunch of arguments of a function. Is there a way to loop over all arguments ? I am doing it the way represented in following code, but want to see if there is a compact way to do this.,

 void methodA(int a1, int a2, int b1, double b2){   
        //.. some code 
        methodB(a1, f(a1));
        methodB(a2, f(a2));
        methodB(b1, f(b1));
        methodB(b2, f(b2));
        // more code follows ...

   }

int f(int a){
      // some function. 
   return a*10;
}

double  f(double b){
   return b/2.0;
}

Upvotes: 5

Views: 7501

Answers (3)

parapura rajkumar
parapura rajkumar

Reputation: 24413

Depending on what you are trying to do. The simplest thing might to revisit your function and see if it can take an array or std::vector as an argument. Might be much simpler that going the variadic route

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 477512

You could use variadic templates:

template <typename T, typename ...Args>
void methodAHelper(T && t, Args &&... args)
{
  methodB(t, f(t));
  methodAHelper(std::forward<Args>(args)...);
}

void methodAHelper() { }

template <typename ...Args>
void methodA(Args &&... args)
{
  // some code
  methodAHelper(std::forward<Args>(args)...);
  // some other code
}

You can possibly get rid of the && and the forwarding if you know that your methodB call doesn't know about rvalue references, that would make the code a bit simpler (you'd have const Args &... instead), for example:

methodAHelper(const T & t, const Args &... args)
{
  methodB(t, f(t));
  methodAHelper(args...);
}

You might also consider changing methodB: Since the second argument is a function of the first argument, you might be able to only pass the first argument and perform the call to f() inside the methodB(). That reduces coupling and interdependence; for example, the entire declaration of f would only need to be known to the implementation of methodB. But that's depends on your actual situation.

Alternatively, if there is only one overload of methodB whose first argument is of type T, then you could just pass a std::vector<T> to methodA and iterate over it:

void methodA(const std::vector<T> & v)
{
  // some code
  for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
    methodB(*it, f(*it));
  // some more code
}

int main() { methodA(std::vector<int>{1,2,3,4}); }

Upvotes: 6

Luchian Grigore
Luchian Grigore

Reputation: 258648

Yes there is, the concept you're looking for is called a variadic function.

Upvotes: 1

Related Questions