Calling different methods with the same signature using a template similar to a mechanism

I have this code:

struct C
{
   int d1;
   int d2;
};

struct A
{
      void  write(C data)
      {
      }
};

struct B
{
      void use(C data)
      {
      }
};

Now I want to define a new class that uses Aor B, and will call their method writeand use. Something like that:

template <class T>
struct D
{
     T t;
     D(T myT) { t=myT; }
     void myFunct(C data)
     {
         // t.????(data);
     }
};

As you can see if the two classes have similar method names, it would be easy to implement D, but since Athey Bhave different methods, then I need to tell the compiler which method it should use. How can i do this?

I do not want to change Aeither B, and I also do not want to subclass Aand Bto create a method with the same name.

I need a way to tell the compiler which method to use as part of the template, is this possible?

+4
3

- D:

template <class T, void (T::*fun)(C)>
struct D
{
    T t;

    void myFunct(C data)
    {
        (t.*fun)(data);
    }
};

D:

D<A, &A::write> da;
D<B, &B::use> db;
+10

, :

template <class T>
struct DTraits;

template <>
struct DTraits<A> {
  static void call(A &obj, C data) { obj.write(data); }
};

template <>
struct DTraits<B> {
  static void call(B &obj, C data) { obj.use(data); }
};

template <class T>
struct D
{
  void myFunct(C data)
  {
    DTraits<T>::call(t, data);
  }
};
+9

For completeness only, there is another possible solution that uses if constexpr, determines the type, and requires C ++ 17 support:

void myFunct(C data)
{
   if constexpr (std::is_same_v<T, A>) {
       t.write(data);
   } else {
       t.use(data);
   }
}

Example

+2
source

Source: https://habr.com/ru/post/1691684/


All Articles