我花了一个小时在我的代码中找到这个问题:
vector<string> & input_variables = parse_xml(xml_path)["variables"];
哪里parse_xml
是返回 a 的函数std::map<std::string, std::vector<std::string> >
。为什么 gcc 没有警告我(使用 -Wall)?我错过了一些标志吗?
我花了一个小时在我的代码中找到这个问题:
vector<string> & input_variables = parse_xml(xml_path)["variables"];
哪里parse_xml
是返回 a 的函数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()
您可以通过将结果显式标记为as来防止这种情况发生const
。