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);
Less verbose alternatives to passing a smart pointer
-
09-07-2023 - |
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
Solution 2
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 typedef
s, I prefer the more verbose version of spelling out std::unique_ptr
and I haven't really found it to be a real problem.