2

我正在阅读有关重载解析的内容,但发现了一些困扰我的内容...在以下代码中:

int const& MaxValue(int const& a, int const& b)
{
    return a > b ? a : b;
}

void SomeFunction()
{
    short aShort1 = 3;
    short aShort2 = 1;
    int const & r2 = MaxValue(aShort1, aShort2); // integral promotion
    //is it safe to pass r2 around before function SomeFunction completes
    // CallSomeOtherFunctionThatCallsSomethingElse(r2);

}

我的理解是创建了两个临时 int,并将它们分配在属于 SomeFunction 的堆栈上。因此,当 MaxValue 返回时,r2 将引用这些临时变量之一(在本例中,是保存值 3 的变量)。因此,传递 r2 应该是安全的。

问题是,如果我的理解没问题,这是标准行为吗(请验证)?如果不是,请解释上面代码中发生的情况。

非常感谢

4

4 回答 4

4

欢迎了解为什么隐式强制转换很烂。你现在有一个临时的引用,它已经被销毁了。希望你不想用它做任何事情。

于 2010-07-04T15:04:40.463 回答
3

是的,您的理解很好,这是标准行为。

除了这个:

因此,传递 r2 应该是安全的。

我不明白。

// 编辑

您应该在这里使用指针而不是引用来实现相同但没有问题。使用 const 引用传递的参数的地址只能在函数内使用,因为它可能指向对象的本地副本。

于 2010-07-04T14:59:56.080 回答
2

简短的回答:这是不安全的。

该标准保证临时变量可以绑定到常量引用,在这种情况下,临时变量的生命周期会扩展到绑定引用的生命周期。在您的特定情况下的问题是实际绑定临时的引用。

当您调用 时MaxValue( s1, s2 ),会创建两个 int 类型的临时变量并将其绑定到参数参数abin MaxValue。这意味着这些临时人员的寿命延长到功能的完成。现在,在您的函数的 return 语句中,您正在对其中一个临时对象进行第二次引用,并且该第二次引用不会延长生命周期。r2不会进一步延长对象的生命周期,并且您有一个悬空引用。

请注意,由于单独编译,编译器不可能从外部知道MaxValue返回的引用是指向参数之一还是指向完全不同的非临时对象:

int const & OtherMaxValue( int const & a, int const & b ) {
   static int value = 0;
   value = (a > b? a : b);
   return value;
}

因此,它不可能猜测是否需要延长任何或哪些临时生命周期。

作为旁注,对于小对象(例如所有整数类型),通过引用传递实际上可能比通过值传递更糟糕。此外,已经有一个std::max实际实现此功能的模板。

于 2010-07-04T15:44:50.687 回答
1

对于简单类型,您应该按值返回和传递。

于 2010-07-04T15:30:17.523 回答