引用临时和警告

reference to a temporary and warnings

本文关键字:警告 引用      更新时间:2023-10-16

我浪费了一个小时在我的代码中找到这个问题:

vector<string> & input_variables = parse_xml(xml_path)["variables"];

其中parse_xml是返回std::map<std::string, std::vector<std::string> >的函数。为什么 gcc 不警告我(用 -Wall)?我错过了一些标志吗?

你引用了一个被销毁的对象。在C++11中,编写了新的语言功能,使此代码非法。如果要使用它,则必须将数据复制或交换到局部变量中。GCC 不会警告您,因为 C++03 没有提供必要的功能来防止这种情况。

从技术上讲,operator[] 的返回值是一个左值。不幸的是,它即将被它的主人std::map摧毁。

GCC 不会警告您,因为从技术上讲,没有什么可警告的。

parse_xml() 按值返回std::map,这是一个临时值。调用 operator[] 将返回引用。编译器无法在本地知道此引用实际上是临时std::map的一部分。据编译器所知,operator[]可能会返回对全局或其他内容的引用。

临时变量的成员变量被视为临时变量

,它与外部临时变量的生存期相关联。但是函数的返回值(如operator[]不是那么链接。

它没有警告您的原因是,您通过一系列有效步骤获得了无效操作:

struct X
{
    int c;
    int & operator [] (int) { return c; } /* this is perfectly OK */
};
X f()
{
    return X(); /* this is perfectly OK */
}
int main()
{
    int &x = f()[1]; /* can apply [] on temporary, therefore OK */
}

您可以通过将f()的结果显式标记为 const 来防止这种情况发生。