如何有效地将左值或右值绑定到同一引用?

时间:2019-02-08 22:45:28

标签: c++ reference ternary-operator rvalue lvalue

假设您有一个C ++函数,该函数使用(const)参数的更改版本。

MyObject alter_obj( MyObject const & obj ); // Creates new, altered object

void func( MyObject const & original ) {
    MyObject const & altered( alter_obj( original ) );
    // ...
}

由于“最重要的const”导致的临时生存期延长,因此可以正常工作。如果alter_obj()满足返回值优化的要求,也将非常有效,因为RVO表示不需要复制通过值返回的更改对象。

如果您根本不做更改,那也将很有效:

void func( MyObject const & original ) {
    MyObject const & not_altered( original );
    // ...
}

对给定对象的附加引用基本上是免费的,而没有产生复制的性能开销。

但是说需求有所变化,您想根据运行时条件选择是否进行更改。天真地,我希望使用三元运算符来组合前面的两种方法会很有效,在可能的情况下直接绑定原始对象,或者在没有的时候绑定临时对象。

MyObject alter_obj( MyObject const & obj ); // Creates new, altered object

void func( MyObject const & original ) {
    // ...
    MyObject const & possibly_altered( 
        apply_alteration ? 
        alter_obj( original ) : 
        original 
    );
    // ...
}

但是,这种方法似乎没有我希望的那样有效。三元运算符显然需要最后两个参数match on lvalue/rvalue status,而不仅仅是标称类型。这意味着,当采用假(无更改)分支时,通过在original上调用MyObject的副本构造函数来创建一个右值临时对象。如果复制MyObject并非无关紧要,则由于进行这种“虚假”复制会导致性能下降。

有没有解决这个问题的好方法?是否可以有效地将本地引用绑定到另一个现有引用或临时引用(基于运行时值的选择)而无需创建其他副本?

2 个答案:

答案 0 :(得分:4)

我将创建单独的函数,该函数接受引用并调用它,如下所示:

void func( MyObject const & original ) {
    if (apply_alteration)
        func_internal(alter_obj(original));
    else
        func_internal(original);
}

void func_internal( MyObject const & possibly_altered) {
    // ...
}

答案 1 :(得分:0)

也许要向func()添加第二个参数?

void func( MyObject const& original, bool modify = false ) {
    if ( modify )  MyObject const & altered( alter_obj( original ) );
    else MyObject const & not_altered( original ); 
}

可能会实现您想要的...