代码之家  ›  专栏  ›  技术社区  ›  Alexey Malistov

是否可以更改临时对象并将其作为参数传递?

  •  3
  • Alexey Malistov  · 技术社区  · 15 年前

    是否可以更改临时对象并将其作为参数传递?

    struct Foo {    
       Foo& ref() { return *this; }
       Foo& operator--() { /*do something*/; return *this; }
       // another members
    };
    Foo getfoo() { return Foo(); } // return Foo() for example or something else
    void func_val(Foo x) {}
    void func_ref(const Foo & x) {}
    
    int main() {
       func_val(--getfoo());     // #1 OK?
       func_ref(getfoo());       // #2 OK?
       func_ref(getfoo().ref()); // #3 OK?
       // the following line is a real example 
       //    using --vector.end() instead of --getfoo()
       func_ref(--getfoo());     // #4 OK? 
    
       const Foo & xref = --getfoo(); //  Does const extend the lifetime ?
       func_ref(xref);     // #5 OK? 
       func_val(xref);     // #6 OK? 
    
    }
    

    众所周知,将临时对象分配给const引用会延长此临时对象的生存期。我的代码中有4行和5行呢? 引用x在函数func_ref中是否始终有效? 问题是,operator——返回一些引用,编译器看不到这个引用和我们创建的临时引用之间的任何关系。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Johannes Schaub - litb    15 年前
    func_val(--getfoo());     // #1 OK?
    

    好的,好的。这个 operator-- 是一个成员函数,它被调用并返回自身(左值引用自身)。然后将对象复制到 func_val . 请注意,不允许应用返回值优化,因为临时 getfoo() 以前绑定到引用。

    func_ref(getfoo());       // #2 OK?
    

    好的,好的。呼叫 获取GET FULL() 返回绑定到常量引用的临时变量。需要一个复制构造函数,但实现可能会优化它的调用。在包含对的调用的完整表达式结束之前,临时变量一直存在。 func_ref (这里是整个表达式语句)。

    func_ref(getfoo().ref());
    

    是的,好的。不需要复制构造函数,因为我们将常量引用绑定到表示对象本身的左值,而不是临时的。

    // the following line is a real example 
    //    using --vector.end() instead of --getfoo()
    

    这不需要工作。想想这样一种情况 vector.end() 返回A T* (允许)。不允许修改非类类型的值,因此在这种情况下,这将是格式错误的。

    func_ref(--getfoo()); 
    

    好的,好的。参数的计算方式为 #1 ,但结果左值直接传递,常量引用绑定到它。在这个意义上,它等于 #3 (减量副作用除外)。

    const Foo & xref = --getfoo();
    

    标准措辞并不完全清楚。它当然只打算延长尚未绑定到引用的对象的寿命。但在我们的情况下, --getfoo() 生成一个左值,该值引用以前绑定到引用的临时对象。可能值得向委员会提交一份缺陷报告(我也可能遗漏了要求临时对象不受引用限制的措辞)。

    在任何情况下,预期的行为都是破坏 获取GET FULL() 初始化结束时 xref 如此 XREF 将成为悬而未决的参考。

    问题是,operator——返回一些引用,编译器看不到这个引用和我们创建的临时引用之间的任何关系。

    完全正确(但仅适用于 XREF 会发疯的。在所有其他情况下,你想要的行为(或者我相信你想要的)都是实现的。

        2
  •  4
  •   MSalters    15 年前

    临时工总是活在 满的 在其中创建它们的表达式。因此,在 表达式语句 func_val(--getfoo()); ,临时返回的生存期 getfoo() 表达式不需要任何扩展。这句话直到后来才结束 func_val() 回来了。