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