代码之家  ›  专栏  ›  技术社区  ›  Ed The ''Pro'' Simon Klee

在两个选项之间向类传递参数

  •  0
  • Ed The ''Pro'' Simon Klee  · 技术社区  · 6 年前

    如何传递类型为的对象 Push Pull 变成一个类型的对象 Object Pool 是吗?

    我在模拟一个 对象池 在C++中。我做了一个函数 Request() 它可以接收 拉动 推动 是的。

    有可能吗?如果是,怎么做?

    提前谢谢你 是的。


    下面是代码示例:

    template <class T>
    class ObjectPool {
        public:
            T Request(T* Object) {
                // This is the part that seems unclear to me.
                // Basically, in Pseudocode it looks like:
                // if Object.type == Pull, then do:
                //     Steps to Generate an Object.
                // else if Object.type == Push:
                //     Steps to store an Object.
            }
    
            ObjectPool() {
            }
    
            ~ObjectPool() {
            }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc RAHUL KUMAR    6 年前

    如果池类是在请求参数上模板化的:

    你有两个选择:

    1. 把你的假代码变成代码:

      T Request (T* Object) {
           static_assert(std::is_same_v<T,Push> or std::is_same_v<T,Pull>,
               "Unsupported pool element type");
           if constexpr (std::is_same_v<T,Pull>) {
               /* do stuff for Pulls */
           }
           else { // i.e. std::is_same_v<T,Push> {
               /* do stuff for Pushes */
           }
      };
      
    2. 不提供一般实现,而是提供两个专门化 Pull 为了 Push 分别是。

      template <typename T>
      class Pool{
          /* ... */
          T Request (T* Object);
          /* ... */
      };
      
      template<> Pool<Pull>::Request(Pull* pull) { /* etc. */ }
      template<> Pool<Push>::Request(Push* push) { /* etc. */ }
      

    如果池类未在请求参数上模板化:

    你的问题需要更具体,但是:

    1. (正如@tyker和@someprogrammerdude建议的那样)可以重载请求方法:

      class Pool {
          /* ... */
          SomeType request(const Push& p);
          SomeType request(const Pull& p);
      };
      
    2. 您可以将请求方法模板化到请求类型上:

      class Pool {
          /* ... */
          template <typename T>
          SomeType request(const T& request_param);
      };
      
    3. 你可以用一个 variant ,其中,值可以有一种类型或另一种类型,如两种类型的(不相交)并集:

      class Pool {
          /* ... */
          using request_param_type = std::variant<Push, Pull>;
          template <typename T>
          SomeType request(request_param_type request_param);
      };
      

      然后,您可以让代码显式地决定(在运行时)为哪个类做什么。它不会是模板化代码,也就是说,您可以在没有实现的情况下公开头。

      现在上面的代码有点问题,因为我写它的方式,您正在复制 推动 拉动 对象,您可能不想这样做。在这种情况下,请尝试:

      template<class...Ts>
      using variant_of_const_refs = std::variant<std::reference_wrapper<const Ts>...>;
      
      class Pool {
          /* ... */
          using request_param_type = variant_of_const_refs<Push, Pull>;
          template <typename T>
          SomeType request(request_param_type request_param);
      }
      
        2
  •  3
  •   user30701    6 年前

    可以通过继承来实现,pull和push对象都是从父类继承的。

    class Push: public BaseClass { /* ... */ };
    class Pull: public BaseClass { /* ... */ };
    
    void Request(BaseClass* action) { /* ... */ }
    

    所以你可以给以太一个拉或推对象到你的请求功能。