管道运算符

时间:2016-10-11 19:43:15

标签: c++ operator-overloading rvalue-reference

我尝试使用虚拟管道类的一些通用实现进行rvalue引用。

template<class I, class O>
class Pipeline
{
    vector<I> _inputs;
    virtual O Execute(void)
    { return foobar( _inputs ) }
};

我想实现运算符| (管道)将多个管道组合在一起:
编辑:用指针更改代码,以便它匹配我的下一个代码示例

// Pipeline* p1, p2, and p3 already exist
Pipeline* p0 = p1 | p2 | p3;
// is equivalent to
p2->_inputs.push_back(p3->execute());
p1->_inputs.push_back(p2->execute());
p0->_inputs.push_back(p1->execute());

我认为右值参考非常适合这个:

template<class I,class O>
Pipeline<I,O>&& operator | (Pipeline<K,O>* a, Pipeline<I,K>* b)
{
    Pipeline* p0 = a;
    Pipeline* p1 = b;

    p0->_inputs.pushback(p1->execute); //inputs is vector<I*> instead of vector<I>
    return std::move(p0);
}

请注意,我更喜欢通过地址而不是值传递,因为typename I和O可能是大对象,而Pipeline在内部工作中可能具有如此大的私有属性。

但是上面的代码显然存在很多内存管理问题: 1 / std :: move(p0)表示永远不会释放/删除p1 2 /如果我直接在a和b而不是p0 p1上工作,我会松开原始指针吗?

有人可以帮助我并告诉我如何为管道操作员使用rvalue ref吗?

编辑:据@Alexey Guseynov说,我的例子不适合rvalue ref。而不是功能代码(Minimal Complete Verifiable示例)我正在寻找关于为什么&amp;&amp;在这里是无效的,我们什么时候应该使用它们:它们背后的哲学是什么,它们到底带来了什么。 提前谢谢

1 个答案:

答案 0 :(得分:0)

声明中的参数类型必须与您使用的参数类型相匹配。所以如果你自己使用对象:

call.Pipeline p0,p1,p2,p3;
p0 = p1 | p2 | p3;

然后运营商|必须拿走物品。在您的情况下,它必须const Pipeline&。请注意,语义operator |不会修改它的操作数,因此尽管允许,您也不应使用Pipeline&

Rvalue引用不是一个很好的返回类型:它们不是为了在这里使用而设计的。您将返回对不再存在的临时对象的引用。你应该在这里返回一个值。

所以在你所展示的代码中没有指针的位置,因此内存管理没有问题。