Home > front end >  How can I decrease the number of overloaded functions
How can I decrease the number of overloaded functions

Time:02-02

I want to know if there is an approach to decrease the number of overloaded function (function edit) in the below code.

 class foo
  {
  public:
      foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
      void edit(int new_a);
      void edit(char new_b);
      void edit(float new_c);
      void edit(int new_a, char new_b);
      void edit(int new_a, float new_c);
      void edit(char new_b, float new_c);
      void edit(int new_a, char new_b, float new_c);
      void info();
  private:
     int   a;
     char  b;
     float c;
  };

Here is the implementation of the edit functions :

void foo::edit(int new_a)
{
    a = new_a;
}
void foo::edit(char new_b)
{
    b = new_b;
}
void foo::edit(float new_c)
{
    c = new_c;
}
void foo::edit(int new_a, char new_b)
{
    a = new_a;
    b = new_b;
}
void foo::edit(int new_a, float new_c)
{
    a = new_a;
    c = new_c;
}
void foo::edit(char new_b, float new_c)
{
    b = new_b;
    c = new_c;
}
void foo::edit(int new_a, char new_b, float new_c)
{
    a = new_a;
    b = new_b;
    c = new_c;
}

The edit function will let the user change the parameters of the object as he wishes. But the thing is that if we add a new parameter we have to add to many overloaded function and I thought there should be a better way.

Here with 3 parameters we need 7 overloaded functions but if we had 4 parameters (a, b, c and d) then we had to develop 14 overloaded function! That's why I think there should be a better approach.

Thanks.

CodePudding user response:

With variadic and (ab)using std::get<T> on std::tuple, you might do

template <typename... Ts>
void edit(Ts... values)
{
    ((std::get<Ts&>(std::tie(a, b, c)) = std::get<Ts&>(std::tie(values...))), ...);
}

Demo.

Note: I use std::get<Ts&>(std::tie(values...)) instead of simply values to get error with duplicated input types(edit(42, 42);).

CodePudding user response:

You can avoid the huge number of overloads and still allow the caller to set more than one member in a single expression:

class foo
  {
  public:
      foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
      foo& edit(int new_a) { a = new_a; return *this;}
      foo& edit(char new_b) { b = new_b; return *this; }
      foo& edit(float new_c) { c = new_c; return *this; }
      
  private:
     int   a;
     char  b;
     float c;
};

int main() {
    foo f(1,'c',2.0);
    f.edit(42).edit(42.0f).edit('a');
}

Adding a member requires you to write one overload rather than N to support all combinations.

CodePudding user response:

The previous solutions are quite fine, but suppose that all elements have a different type.

A possibility is to still use a variadic template, and in the call to indicate with a string which element must be modified.
This would allow the possibility to have the same type for different elements.

#include <iostream>
#include <string>

class foo {
  public:
      foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
      void edit() {};
      template<typename T1, typename... T2>
      void edit (const std::string& id, T1 var1, T2... var2) {
          if (id == "a") a = var1;
          else if (id == "b") b = var1;
          else if (id == "c") c = var1;
          edit(var2...);
      };
      void info();
  //private:
     int   a;
     char  b;
     float c;
};

  std::ostream& operator<<(std::ostream& os, const foo& obj) {
    std::cout << "a = " << obj.a <<  " b = " << obj.b << " c = " << obj.c;
    return os;
  }

int main() {
    foo example(1, 'a', 2.0);
    example.edit("c", 3.0f, "b", 'g', "a", 5);
    std::cout << example << std::endl;
}

CodePudding user response:

Given your edit functions that modify a single member:

void edit(int new_a)
{
    a = new_a;
}
void edit(char new_b)
{
    b = new_b;
}
void edit(float new_c)
{
    c = new_c;
}

You can define a single function in C 11 using variadic templates to support multiple parameters in terms of multiple calls with a single parameter:

template< typename FirstType, typename ...OtherTypes >
void edit(FirstType ft, OtherTypes ...ot)
{
    edit(ft);
    edit(ot...);
}

Using C 17, fold expressions can make this function even simpler.

template< typename ...Types >
void edit(Types ...types)
{
    (edit(types), ...);
}
  •  Tags:  
  • Related