Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify multiple functions with same logic but different parameter type?

Tags:

c++

void functionA(A a){
  for(auto x: vector_of_x) {
    // duplicate code, which cannot be moved to a common function
    x.abc(a);
    // some more duplicate code, which cannot be moved to a common function
  }
}

void functionB(B b){
  for(auto x: vector_of_x) {
    // duplicate code, which cannot be moved to a common function
    x.def(b);
    // some more duplicate code, which cannot be moved to a common function
  }
}

The duplicate code in functionA and functionB is quite a lot, so I'm looking to remove duplicate code. What's the best way to achieve it?

like image 273
gimbup Avatar asked Dec 28 '25 14:12

gimbup


1 Answers

You can merge functionA and functionB into a function template, where it's customizable whether abc or def gets called.

template <auto MemberFunction, typename T>
void function(T t){
  for(auto x: vector_of_x) {
    // duplicate code, which cannot be moved to a common function
    (x.*MemberFunction)(t);
    // some more duplicate code, which cannot be moved to a common function
  }
}

void functionA(A a){
  function<&A::abc>(a);
}

void functionB(B b){
  function<&B::def>(b);
}

However, member function pointers are a bit tricky syntax-wise, and they aren't very flexible. For example, what if you wanted to also debug-print something instead of just calling A::abc? Therefore, you would use lambda expressions (or any other invocable object) in most cases:

template <typename F>
void function(F f){
  for(auto x: vector_of_x) {
    // duplicate code, which cannot be moved to a common function
    std::invoke(f, x); // or x(f), if that's sufficient
    // some more duplicate code, which cannot be moved to a common function
  }
}

void functionA(A a){
  function( [&a](X& x) { x.abc(a); } );
}

void functionB(B b){
  function( [&b](X& x) { x.def(b); } );
}

The latter solution is very idiomatic; it's also what algorithms such as std::for_each in the standard library do.

like image 146
Jan Schultke Avatar answered Dec 30 '25 03:12

Jan Schultke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!