2012-04-23 42 views
0

我已经失去了一个小时找到我的代码这个问题:引用到一个临时和警告

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

其中parse_xml是返回std::map<std::string, std::vector<std::string> >的功能。为什么gcc没有警告我(带-Wall)?我错过了一些标志?

+0

[插入'valgrind'或类似工具的广告]。不,但真的,它会为自己节省时间学习使用它们;)。 – FatalError 2012-04-23 16:33:50

+0

请您列出您的完整编译标志。特别是您的警告标志 – 111111 2012-04-23 16:34:10

+0

临时的生命周期不应该延长,因为12.2/5表明? – sharptooth 2012-04-23 16:34:21

回答

2

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

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

+0

您确定这将在C++ 11中无效吗?这里的问题的确是'parse_xml'的返回是一个临时对象,而不是一个常量对象。 – 2012-04-23 16:59:58

+0

我正在使用C++ 03 – 2012-04-23 21:08:18

+0

@Let_Me_Be:在C++ 11中,可以基于左值或右值重载成员函数(包括operator [])。这意味着'operator []'可以返回一个临时的 - 正确地阻止这个代码。 'const'与此完全无关。 – Puppy 2012-04-23 21:33:41

0

它为什么不提醒你的原因是因为你是通过有效的步骤序列获得的无效操作:

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结果发生。

+0

'const' rvalues是不好的。例如,它们不能被移动。 – Puppy 2012-04-23 21:34:30

+0

@DeadMG在ANSI C++? – 2012-04-24 10:34:26

+0

ANSI? ANSI从不标准化任何版本的C++。目前只有ISO C++ - 去年标准化的当前版本。 – Puppy 2012-04-24 11:29:37

1

海湾合作委员会并没有警告你,因为技术上没有什么可警告的。

parse_xml()按值返回std::map,这是一个临时值。调用operator[]返回一个参考。编译器不能知道本地该参考实际上是部分std::map临时。对于所有的编译器都知道,operator[]可能会返回一个对全局或其他东西的引用。

临时成员变量被认为是临时的,它与外部临时的生命周期相关联。但是函数的返回值(如operator[])是而不是这样链接。