返回函数局部变量作为引用

Returning function-local variable as reference

本文关键字:引用 局部变量 函数 返回      更新时间:2023-10-16

我找到了这个源代码:

inline GUID& WString2Guid(wstring src)
{
    static GUID result;
    HRESULT hr = ::CLSIDFromString(W2OLE(const_cast<WCHAR*>(src.c_str())), &result);
    if (FAILED(hr)) {
        //ERROR: The string '%s' is not formatted as a GUID!
        throw(E_INVALIDARG);
    }
    return result;
}

在这里返回引用有什么用?调用代码无论如何都无法获得引用,因为到那时变量已经离开了它的作用域。那么这个小小的&符号有什么区别吗?

为了澄清/扩展这个问题:在同一个示例程序中,函数被称为
GUID guid = WString2Guid(id); // way 1

如果我想使用引用,我不是必须调用

吗?
GUID& guid = WString2Guid(id); // way 2

?

还有一个问题;为什么CLSIDFromString函数与::作用域操作符之前调用?这只有在另一个局部函数用相同的名字声明时才有意义,不是吗?

No。resultstatic局部变量,因此即使在函数退出后它仍然存在。不要将它与非静态局部变量混淆。

::CLSIDFromString中的

::告诉编译器从全局命名空间中选择CLSIDFromString,以防在调用站点中可以看到在其他命名空间中定义了许多CLSIDFromString的定义。

该变量是静态的,因此它将保持有效。不过这是愚蠢的代码,它应该按值返回GUID。

范围操作符可能是个人的风格偏好。

密钥位为static关键字。它将result绑定到函数本身,而不是特定的函数调用。它在一个特定的调用返回后继续存在,因此通过引用返回是安全的。

作用域解析操作符(::)本身在全局命名空间中调用CLSIDFromString。也许代码作者在自己的名称空间中有该函数的另一个版本。编译器会告诉您对函数的调用是否有歧义,因此您需要添加它。即使调用不是二义性的,它在那里也不会伤害任何东西。

回答你的第一个问题——局部变量被声明为静态,这意味着它的内存缓冲区从一个函数调用到另一个函数调用是保留的。