Salut à tous et à toutes !
J'ai pour représentaire un arbre n-aire, une classe Node qui a a priori sémantique d'entité. Histoire d'essayer de gérer la propriété des noeuds correctement, j'ai utilisé un vector de unique_ptr pour représenter les enfants (choix peut être contestable).
Pour construire un arbre à partir des feuilles, j'aimerais écrire ça :
Le compilateur me dit
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 auto f = make_node<int>(5); auto g = make_node<int>(6); std::vector<std::unique_ptr<Node<int>>> children; children.push_back(std::move(f)); children.push_back(std::move(g)); auto e = make_parent<int>(children, 4); // là le compilateur me dit que je parle assez mal le c++ assert( (!f.get()) && !g.get()); // unique_ptr are now emptyDonc je me dis que j'ai foiré en essayant d'éviter la copie du vector dans la fonction friend make_parent:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 error: no matching function for call to make_parent(std::vector<std::unique_ptr<Node<int>, std::default_delete<Node<int> > >, std::allocator<std::unique_ptr<Node<int>, std::default_delete<Node<int> > > > >&, int) auto e = make_parent<int>(children, 4);
J'y suis depuis hier matin, et j'ai lu plein de trucs intéressants sur stack overflow à propos de templates, des friends, des universal references, mais je manque de pratique en la matière (et je ne pourrai pas prétendre avoir tout compris à la théorie des &&
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 template<typename T> class Node; template<typename T, typename ...Args> std::unique_ptr<Node<T>> make_node(Args&& ...args); template<typename T, typename ...Args> std::unique_ptr<Node<T>> make_parent(std::vector<std::unique_ptr<Node<T>>>&& children, Args&& ...args); template<typename T> class Node{ // ... private: Node() = default; Node(const Node&) = delete; Node& operator=(const Node&) = delete; template <typename... Args> Node(Args&&... args ) : m_data(T(std::forward<Args>(args)...)) {} template <typename ...Args> friend std::unique_ptr<Node<T>> make_node(Args&& ...args){ return std::unique_ptr<Node<T>>(new Node<T>(std::forward<Args>(args)...)); } template<typename ...Args> friend std::unique_ptr<Node<T>> make_parent(std::vector<std::unique_ptr<Node<T>>>&& children, Args&& ...args){ std::unique_ptr<Node<T>> ptr = std::make_unique<Node<T>>(new Node<T>(std::forward<std::vector<std::unique_ptr<Node<T>>>>(children), std::forward<Args>(args)...)); for(auto & it : children){ it->m_parent = ptr.get(); ptr->m_children.push_back(std::move(it)); } return ptr; } Node<T>* m_parent = nullptr; // inexistence possible std::vector<std::unique_ptr<Node<T>>> m_children; T m_data; };). Malgré mes tentatives d'écrire la même chose de différentes façon, je ne comprends pas ce que j'ai mal fait, pourriez-vous me l'indiquer je vous prie ?
En vous remerciant,
Partager