Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 传递智能指针的更为简洁的替代方法_C++_C++11_Coding Style_Smart Pointers - Fatal编程技术网

C++ 传递智能指针的更为简洁的替代方法

C++ 传递智能指针的更为简洁的替代方法,c++,c++11,coding-style,smart-pointers,C++,C++11,Coding Style,Smart Pointers,我们都知道并喜欢智能指针的安全性和速度,但不得不调用这样的函数让我很烦: 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)); void Tre

我们都知道并喜欢智能指针的安全性和速度,但不得不调用这样的函数让我很烦:

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));
void TreeNode::addChild(唯一的\u ptr newChild){
儿童推回(标准::移动(新儿童));
}
//这必须这样称呼:
node.addChild(unique_ptr(新树节点(10));
我发现它不必要地冗长冗长。这真的是做事情的最佳方式吗?我不能只传递一个原始指针并在
addChild
内部创建我的
unique\ptr
?这种冗长的替代方法和好处是什么

EDIT:我想添加
TreeNode
可以从中派生,所以仅仅实现
addChild(int-arg)
是不够的。但是在C++14中可以使用函数

在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));
}
#包括
结构X{X(int,int);};
void foo(标准::唯一\u ptr);
模板
内联std::unique_ptr使_唯一(Args&&…Args){
返回std::unique_ptr(新的T(std::forward(args)…);
}
int main(){
foo(make_unique(1,2));
}

您可以使用
typedef
(在C++11中用
替换为
):

另一种方法是,如果您可以控制类型
TreeNode
,则将
typedef
放在类中,并将其称为
UP
或类似的简短名称并使用

void TreeNode::addChild(TreeNode::UP newChild);
请注意,我个人不喜欢那些
typedef
s,我更喜欢拼写
std::unique\u ptr
的更详细版本,我还没有发现这是一个真正的问题。

  • 您可以执行以下操作:

    template<typename...Ts>
    void TreeNode::emplaceChild(Ts&&...args){
        children_.emplace_back(make_unique<TreeNode>(std::forward<Ts>(args)...));
    }
    
  • 要指定要添加的子项的类型,可以使用以下项作为替换项:

    template<typename T, typename...Ts>
    void TreeNode::emplaceChild(Ts&&...args) {
        children_.emplace_back(make_unique<T>(std::forward<Ts>(args)...));
    }
    
    模板
    void TreeNode::安放子对象(Ts&&…args){
    儿童安置在后方(使后方独特(标准::前方(args)…);
    }
    
    然后:

    node.emplaceChild(10);
    
    node.emplaceChild<TreeNode>(10);
    
    node.implaceChild(10);
    

这只会稍微减轻调用中的冗长程度,甚至不会触及函数声明和定义中的冗长程度。请记住,比较应该与调用中的纯new和声明中的原始指针进行比较。@MatteoItalia:从原始问题:…必须调用这样的函数会让我感到非常不舒服此外,您还可以使用
模板void TreeNode::addChild(Args&&…Args)
,inn effect内联
std::make_unique
,从问题中重载
addChild
。结果:
节点。addChild(10)
@MatteoItalia我真的不在乎函数定义或声明是否冗长,我只做一次,我可以随心所欲地对它们进行注释。但是对它的调用应该简短而清晰。我喜欢这个解决方案的一点是,对
foo
的调用没有含糊不清的部分,但事实上它是唯一的指针被传递。@MSalters这是一个非常酷的想法,但我可以再次传递参数并在addChild内部创建对象。不幸的是,TreeNode可以被子类化,因此这不是一个真正的选项。我正在考虑将类型和构造函数参数传递给
addChild
,但我不确定如何ld实现它。(我用enum做了类似的东西,但这似乎太复杂了)我很喜欢我的一些typedef,但这似乎减少了声明/定义的详细程度,而不是调用中的详细程度,这更符合我的目标。定义中的详细程度是出于自我文档的原因,我只需要编写一次。对不起,我应该提到我希望能够将TreeNode子类化。但这是bes到目前为止,我看不出答案!我不认为你需要一个
emplace\u回到那里。这是一个非常奇怪的语法,我似乎还不能完全理解它…好吧,我在你的答案中编辑了一个更简单的示例并接受了它,它确实帮了我很多忙!非常感谢!
template<typename T, typename...Ts>
void TreeNode::emplaceChild(Ts&&...args) {
    children_.emplace_back(make_unique<T>(std::forward<Ts>(args)...));
}
node.emplaceChild<TreeNode>(10);