Менее подробные альтернативы умному указателю
Мы все знаем и любим умные указатели за их безопасность и скорость, но необходимость вызывать такие функции раздражает меня:
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));
Я считаю, что это излишне многословно и долго. Это действительно лучший способ сделать что-то? Разве я не могу просто передать необработанный указатель и создать свой unique_ptr
Внутри addChild
? Каковы альтернативы и каковы преимущества этого многословия?
РЕДАКТИРОВАТЬ: Я хотел бы добавить, что TreeNode
может быть получено из, так что просто реализация addChild(int arg)
не совсем достаточно Но
3 ответа
Вы можете сделать следующее:
template<typename...Ts> void TreeNode::emplaceChild(Ts&&...args){ children_.emplace_back(make_unique<TreeNode>(std::forward<Ts>(args)...)); }
А потом:
node.emplaceChild(10);
Чтобы указать тип добавляемого потомка, вы можете использовать в качестве замены:
template<typename T, typename...Ts> void TreeNode::emplaceChild(Ts&&...args) { children_.emplace_back(make_unique<T>(std::forward<Ts>(args)...)); }
А потом:
node.emplaceChild<TreeNode>(10);
В C++14 вы можете использовать std::make_unique
функция.
В C++11 реализуй это сам, например:
#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));
}
Вы могли бы использовать typedef
(который заменяется на using
в C++11):
using TreeNodeUP = std::unique_ptr<TreeNode>;
упростить код:
void TreeNode::addChild(TreeNodeUP newChild);
Альтернатива, если у вас есть контроль над типом TreeNode
это поставить typedef
внутри класса и назовите это UP
или что-то такое же короткое и использовать
void TreeNode::addChild(TreeNode::UP newChild);
Обратите внимание, что лично мне не нравятся эти typedef
s, я предпочитаю более подробный вариант написания std::unique_ptr
и я действительно не нашел, что это реальная проблема.