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 :
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 empty
Le compilateur me dit
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);
Donc 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
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;
};
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 && ). 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,