【问题标题】:Calling different methods with the same signature using a template like mechanism使用类似模板的机制调用具有相同签名的不同方法
【发布时间】:2018-06-13 03:26:22
【问题描述】:

我有这个代码:

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 的子类来创建具有相同名称的方法。

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

【问题讨论】:

  • 可以使用动态转换,判断T是A还是B,然后调用转换变量的函数
  • @mahdi_12167 - 不要在评论区发布答案
  • @mahdi_12167 这要求AB 是多态的,并否定了D 作为模板所带来的无运行时开销优势。

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


【解决方案1】:

您可以将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;

【讨论】:

    【解决方案2】:

    您可以使用自己的 trait 类轻松做到这一点:

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

    【讨论】:

      【解决方案3】:

      为了完整起见,这里是另一种可能的解决方案,它使用 if constexpr、类型特征并需要 C++17 支持:

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

      Example

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-26
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        • 2014-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多