Как избежать дублирования параметров шаблона во вложенном шаблоне - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть шаблонный класс 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<Node<int>, int>* bst = new BST<Node<int>, int>();

Что немного некрасиво.

Я бы хотел

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

и выведите параметр шаблона T в BST из параметра структуры шаблона.

Я пытался template < template<typename T> class Node>, который, похоже, не работает (T неизвестно в объявлении find()).

Ответы [ 4 ]

0 голосов
/ 05 сентября 2018

Вы должны вложить 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;
};
0 голосов
/ 05 сентября 2018

Вы можете изменить основной шаблон так, чтобы он принимал только один параметр шаблона, и добавить частичную спецификацию.

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

Или добавьте несколько вложенных typedefs.

template <typename T>
struct Node {
    using value_type = T;
    ...
};

template <typename Node>
class BST {
    using T = typename Node::value_type;
    ...
};
0 голосов
/ 05 сентября 2018

Почему не просто

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) {/* ... */}
};
0 голосов
/ 05 сентября 2018

У вас есть несколько возможностей:

  • Проще, и я думаю, что вы хотите:

    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;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...