2012-05-10 41 views
5

此代码段是否有效?C++临时变量生存期

int foo() 
{ 
    std::vector<std::string>& v = std::vector<std::string>(5, "X"); 

    // Do something silly... 

    return 42; 
} 

出于某种原因,我认为暂时std::vector对象(右从分配符号)应该被销毁之后它的建设(从而使参考无效)

但是,调试证明我错了,而且,我意识到我不太明白为什么临时变量在函数返回时被破坏。


我想我有一些基本的东西很强的误解,所以请赐教:)

+0

当你说“调试证明我错了”时,你究竟是什么意思? –

回答

8

还有你的代码是非法–临时对象只能绑定到右值引用或常量左值参考。

VC++恰好允许它作为扩展名(并给出a level 4 warning这样说)。

+1

gcc很好地抱怨这个错误:错误:类型'std :: vector ,std :: allocator >,std :: allocator < std :: basic_string ,std :: allocator >>&从类型'std :: vector ,std ::分配器>,std :: allocator ,std :: allocator >>> – Scottymac

+0

谢谢,不知道那个扩展*(和,已经尝试过'gcc')。* –

+2

@ Yippie-Kai-Yay:那么你应该建立4级警告。 ; - ] – ildjarn

2

您有一个对释放对象的引用。它的工作原理是“纯粹的运气”(参见C++编程语言,第10.4.10节“临时对象”)。你不能保证它能在每个编译器中工作。

只有当它被绑定到const引用时,才能确定临时的生存期被延长。

+2

在这种情况下,这不是纯粹的运气,它是OP使用的编译器提供的语言扩展。 – ildjarn

+0

@ildjarn我只是引用Stroustrup的舌头。关键是它不可移植/非法/不可靠,或者任何你想称之为的东西。 – frozenkoi

+3

这不是便携式,同意,但它也不是非法的;只要扩展不会影响格式正确的代码的行为,并且编译器发出诊断(警告计数),C++标准(§1.4/ 8)就特别允许语言扩展。 – ildjarn

3

临时的正常生命周期是直到完整的 表达式的结尾;它不一定会在使用中立即销毁 。如果使用临时初始化引用 它的生命周期将延长到与引用的一致(与 构造函数的初始化程序列表中创建的临时例外的明显例外)。

当然,你的代码是非法的;如果引用是一个非常量,它只能用某种左值初始化它 。但如果它是合法的(至少有一个编译器接受它) ,则延长的生命周期应该是 以匹配参考值。