Question

We all know and love smart pointers for their safety and speed, but having to call functions like this bugs me out:

void TreeNode::addChild(unique_ptr<TreeNode> newChild){
    children_.push_back(std::move(newChild));
}
//This has to be called like so:

node.addChild(unique_ptr<TreeNode>(new TreeNode(10));

I find it to be unnecessarily verbose and long. Is this really the best way to do things? Can't I just pass a raw pointer and create my unique_ptr inside of addChild? What are alternatives and what are the benefits of this verbosity?

EDIT: I wanted to add that TreeNode can be derived from, so just implementing addChild(int arg) isn't quite enough. But

Was it helpful?

Solution 2

  • You may do the following:

    template<typename...Ts>
    void TreeNode::emplaceChild(Ts&&...args){
        children_.emplace_back(make_unique<TreeNode>(std::forward<Ts>(args)...));
    }
    

    And then:

    node.emplaceChild(10);
    
  • To specify the Type of child to add, you may use as replacement:

    template<typename T, typename...Ts>
    void TreeNode::emplaceChild(Ts&&...args) {
        children_.emplace_back(make_unique<T>(std::forward<Ts>(args)...));
    }
    

    And then:

    node.emplaceChild<TreeNode>(10);
    

OTHER TIPS

In C++14 you can use std::make_unique function.

In C++11 implement it yourself, e.g.:

#include <memory>

struct X { X(int, int); };

void foo(std::unique_ptr<X>);

template<class T, class... Args>
inline std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

int main() {
    foo(make_unique<X>(1, 2));
}

You could use a typedef (which is replaced by using in C++11):

using TreeNodeUP = std::unique_ptr<TreeNode>;

to simplify some code:

void TreeNode::addChild(TreeNodeUP newChild);

An alternative, if you have control over the type TreeNode is to put the typedef inside the class and call it UP or something similarly short and use

void TreeNode::addChild(TreeNode::UP newChild);

Note that I personally don't like those typedefs, I prefer the more verbose version of spelling out std::unique_ptr and I haven't really found it to be a real problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top