Perfect forwarding d'un vecteur de unique_ptr ?
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:
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:
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:
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 ? :oops:
En vous remerciant,