使用类似机制的模板使用相同的签名调用不同的方法

时间:2018-01-03 12:41:33

标签: c++ c++11 templates methods

我有这段代码:

struct C
{
   int d1;
   int d2;
};

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

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

现在,我想定义一个使用AB的新类,并调用他们的writeuse方法。像这样的东西:

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

正如您所看到的那两个类是否具有相似的方法名称,那么实现D会很容易,但由于AB有不同的方法,所以我需要告诉编译器它应该使用哪种方法。我怎样才能做到这一点?

我不想更改AB而且我也不想创建AB的子类来创建一个具有相同名称的方法。

我想要一种方法告诉编译器使用哪种方法作为模板的一部分,是否可能?

3 个答案:

答案 0 :(得分:10)

您可以将pointer to member-function作为第二个模板参数传递给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;

答案 1 :(得分:9)

您可以使用自己的特质类轻松完成此操作:

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);
  }
};

答案 2 :(得分:2)

为了完整起见,这里是另一种可能的解决方案,它使用PM> Update-Package Microsoft.AspNet.Razor -reinstall ,类型特征并需要 C ++ 17 支持:

if constexpr

Example