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

R.M*_*.M. 6 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 ) );
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是正常的,因为临时的寿命延长,因为"最重要的const".如果alter_obj()满足返回值优化的要求,它也是相当有效的,因为RVO意味着不会不必要地复制由值返回的更改对象.

如果你根本没有改变它也会很有效:

void func( MyObject const & original ) {
    MyObject const & not_altered( original );
    // ...
}
Run Code Online (Sandbox Code Playgroud)

对给定对象的附加引用基本上是免费的,没有制作副本的任何性能开销.

但是说需求会有所改变,并且您希望根据运行时条件选择是否进行更改.天真地,我原本以为使用三元运算符来组合前两种方法将是有效的,在可能的情况下直接绑定原始对象,或者如果不是则绑定临时对象.

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 
    );
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但是,似乎这种方法并不像我希望的那样有效.三元运算符显然要求最后两个参数匹配左值/右值状态,而不仅仅是标称类型.这意味着当采用false(无更改)分支时,通过调用MyObject的复制构造函数来生成rvalue临时original.如果要复制MyObject并不容易,那么由于制作了这个"虚假"副本,可能会造成性能损失.

这有什么好办法吗?是否可以有效地将本地引用绑定到另一个现有引用或临时(基于运行时值的选择)而不创建其他副本?

Iły*_*sov 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) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)