Менее подробные альтернативы умному указателю

Мы все знаем и любим умные указатели за их безопасность и скорость, но необходимость вызывать такие функции раздражает меня:

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);

Обратите внимание, что лично мне не нравятся эти typedefs, я предпочитаю более подробный вариант написания std::unique_ptr и я действительно не нашел, что это реальная проблема.

Другие вопросы по тегам