3

参考:来自 C++ 模板的代码片段:完整指南

// maximum of two values of any type (call-by-reference) 
template <typename T> 
inline T const& max (T const& a, T const& b) 
{ 
    return a < b ? b : a; 
} 

// maximum of two C-strings (call-by-value) 
inline char const* max (char const* a, char const* b) 
{ 
    return std::strcmp(a,b) < 0 ? b : a; 
} 

// maximum of three values of any type (call-by-reference) 
template <typename T> 
inline T const& max (T const& a, T const& b, T const& c) 
{ 
    return max (max(a,b), c); // error, if max(a,b) uses call-by-value 
} 

int main () 
{ 
    ::max(7, 42, 68); // OK 

    const char* s1 = "frederic"; 
    const char* s2 = "anica"; 
    const char* s3 = "lucas"; 
    ::max(s1, s2, s3); // ERROR 

} 

上述代码的陈述问题:

问题是,如果你为三个 C 字符串调用 max(),语句

返回最大值(最大值(a,b),c);变成一个错误。这是因为对于 C 字符串,max(a,b) 创建了一个新的临时本地值,该值可能由函数通过引用返回。

问题> 我还是不明白上面的几点。为什么

“您不能使用三参数版本来计算三个 C 字符串的最大值”?

// 更新

const int* fReturnValue(const int *i)
{
    return i;
}

int main()
{
    int i = 3;
    const int* i4= fReturnValue(&i);

    cout << &i << endl;
    cout << i4 << endl;
}

观察:两行返回相同的地址。所以我假设在函数 fReturnValue 中,函数按值返回,但它不会伤害 b/c,它是一个指针地址。换句话说,返回地址仍然有效。

真的吗?

4

1 回答 1

11

问题是C 字符串风格的max按值返回,而不是按值获取参数。通用的 3 路max函数被声明为返回一个引用,但C 字符串 max返回一个值,这将导致返回一个临时引用,该引用在您访问它之前就已失效。

更新:您添加的新代码不等同于您原来的问题。这个会:

const int*& fReturnValue(const int *i)
{
    return i;
}

请注意,它fReturnValue返回对局部变量的引用i,其生命周期在函数返回时结束。因此该函数返回对无效对象的引用。尝试使用该更改编译您的代码,您应该会从几乎每个编译器中收到警告。

于 2013-02-20T20:50:27.507 回答