代码之家  ›  专栏  ›  技术社区  ›  PinkTurtle

如何避免嵌套模板中的模板参数重复

  •  1
  • PinkTurtle  · 技术社区  · 6 年前

    我有一个模板化的BST类和一个节点结构,如下所示:

    template <typename T>
    struct Node {
    
        T value;
        Node* left;
        Node* right;
    };
    
    template <typename Node, typename T>
    class BST {
    
    public:
    
        Node* m_root;
    
    public:
    
        BST() {
            m_root = NULL;
        }
    
        bool find(T value, Node** parent, Node** location) {/* ... */}
    }
    

    我需要知道BST类中结构的模板参数,并按如下方式实例化BST:

    BST<Node<int>, int>* bst = new BST<Node<int>, int>();
    

    BST<Node<int>>* bst = new BST<Node<int>>();
    

    并从struct-template参数推导出BST中的T-template参数。

    template < template<typename T> class Node> 似乎不起作用( T 是未知的 find() 声明)。

    4 回复  |  直到 6 年前
        1
  •  3
  •   Jarod42    6 年前

    你有几种可能:

    • 越简单,我想你想要的是:

      template <typename T>
      class BST {
      public:
          Node<T>* m_root = nullptr;
      
      public:
          BST() = default;
      
          // ...
      };
      

      有用法

      BST<int> bst;
      
    • 另一个是专业化:

      template <typename T> class BST;
      
      template <typename T>
      class BST<Node<T>> {
      public:
          Node<T>* m_root = nullptr;
      
      public:
          BST() = default;
      
          // ...
      };
      

      使用方法:

      BST<Node<int>> bst;
      
    • 最后一个,模板参数:

      template <template <typename> class N, typename T>
      class BST {
      public:
          N<T>* m_root = nullptr;
      
      public:
          BST() = default;
      
          // ...
      };
      

      有用法

      BST<Node, int> bst;
      
        2
  •  2
  •   songyuanyao    6 年前

    template <typename T>
    class BST;
    
    template <template <typename> class C, typename T>
    class BST<C<T>> {
        using Node = C<T>;
    public:
        BST() {
            m_root = NULL;
        }
    
        bool find(T value, Node** parent, Node** location) {/* ... */}
    };
    

    然后你就可以像这样使用它

    BST<Node<int>>* bst = new BST<Node<int>>(); // deduce C as Node, T as int
    

    或者添加一些嵌套的typedef。

    template <typename T>
    struct Node {
        using value_type = T;
        ...
    };
    
    template <typename Node>
    class BST {
        using T = typename Node::value_type;
        ...
    };
    
        3
  •  2
  •   binky    6 年前

    为什么不干脆

    template <typename T>
    class BST {
    
    public:
    
        Node< T >* m_root;
    
    public:
    
        BST() {
            m_root = NULL;
        }
    
        bool find(T value, Node< T >** parent, Node< T >** location) {/* ... */}
    };
    
        4
  •  1
  •   Remy Lebeau    6 年前

    Node 内部 BST

    template <typename T>
    class BST
    {
    public:
        struct Node
        {
            T value;
            Node* left;
            Node* right;
        };
    
        BST() { m_root = NULL; }
    
        bool find(T value, Node** parent, Node** location) {/* ... */}
    
    private:
        Node* m_root;
    };