Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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+延长返回临时变量的寿命+;11_C++_C++11 - Fatal编程技术网

C++ 是否可以通过使用移动/交换c+延长返回临时变量的寿命+;11

C++ 是否可以通过使用移动/交换c+延长返回临时变量的寿命+;11,c++,c++11,C++,C++11,我有一个基本节点所在的树(未显示所有方法): 从该抽象类可以派生子类,这些子类实现了容纳所有子节点所需的容器。 如前所述,我还有一个自定义迭代器节点\迭代器\基 struct node_iterator_base { virtual ~node_iterator_base() {} virtual node_iterator_base& operator++()=0; virtual node_base* operator->() const =0;

我有一个基本节点所在的树(未显示所有方法):

从该抽象类可以派生子类,这些子类实现了容纳所有子节点所需的容器。 如前所述,我还有一个自定义迭代器节点\迭代器\基

struct node_iterator_base {
    virtual ~node_iterator_base() {}
    virtual node_iterator_base& operator++()=0;
    virtual node_base* operator->() const =0;
    virtual node_base& operator*() const =0;
    virtual bool operator==(const node_iterator_base& x) const =0;
    virtual bool operator!=(const node_iterator_base& x) const =0;
};
template<It>
struct derived_iterator: public node_iterator_base {
    derived_iterator(It I): ci(I) { }
    ...
    It ci;
}
现在的问题是在派生类中实现begin

node_iterator_base& derived_node::begin() const {
    return derived_iterator(container); 
    //This will not work because a temporary variable is passed to a 
    reference
}
我们可以做些什么呢?如果我们改变声明,开始

virtual node_iterator_base begin() const =0;

当然,我可以返回一个指针,但是我的迭代器看起来不像STL迭代器,必须手动销毁它。 我如何返回推荐信?从C++11移动/交换可以帮助我吗? 更多关于我的异构树的信息
简单的答案是不。你不能做你想做的事

中等回答是肯定的。您可以使用
pImpl
模式传递一个facade,该facade包含指向其中接口的指针;它将调用转发到其实现接口(pImpl)。这使得看起来像迭代器一样的值类型可以是多态的,但代价是动态分配和间接寻址

较长的答案是,您正在尝试一个类型擦除迭代器一个类型擦除迭代器。您可以使用pImpl或类似任何函数甚至std函数来实现这一点。然而,C++的迭代器接口具有很大的曲面,在迭代过程中经常交互。迭代器的类型擦除被证明是昂贵的。Boost有任何迭代器为您实现此功能;它们不适合在性能敏感的代码中使用

最好是键入擦除迭代操作本身,而不是迭代器。与迭代器交互相比,您的迭代次数要少得多;通过类型擦除不太频繁的操作,您可以显著提高性能(或者实际上减少浪费)

最后,考虑使用变体代替;如果可以枚举子类,则可以使用它为编译器提供更少的间接寻址和更多信息


boost或C++17中提供了任何类型和变体,也可以自己重新实现。

您的迭代器可能有一个指向多态对象的指针。我认为您是对的,但什么是“键入擦除迭代”?@user
foreach_chicken([&](auto&&chicken){chicken.pulk();});因为您可以公开更多的控制流(例如,处理鸡的缓冲区而不是单个鸡),所以可以在迭代时减少类型擦除的频率。
node_iterator_base& derived_node::begin() const {
    return derived_iterator(container); 
    //This will not work because a temporary variable is passed to a 
    reference
}
virtual node_iterator_base begin() const =0;
node_iterator_base derived_node::begin() {
    return derived_iterator(container); 
   //This will not work either because node_iterator_base is an abstract struct
}