获取临时对象的地址

时间:2010-02-17 12:51:24

标签: c++ rvalue

§5.3.1一元运算符,第3节

  

一元&的结果operator是指向其操作数的指针。 操作数应为左值或限定ID。

在这种情况下,“应该”究竟是什么意思?这是否意味着取一个临时的地址是错误的?我只是想知道,因为g ++只给了我一个警告,而comeau拒绝编译以下程序:

#include <string>

int main()
{
    &std::string("test");
}

g ++ 警告taking address of temporary

comeau 错误expression must be an lvalue or a function designator

有没有人有微软编译器或其他编译器,可以测试这个程序吗?提前谢谢。

7 个答案:

答案 0 :(得分:27)

标准语言中的“应”一词意味着严格的要求。所以,是的,你的代码格式不正确(这是一个错误),因为它试图将地址运算符应用于非左值。

但是,此处的问题不是尝试获取临时的地址。问题是,再次采用非左值的地址。临时对象可以是左值或非左值,具体取决于生成临时对象的表达式或提供对该临时对象的访问权限。在你的情况下,你有std::string("test") - 一个非参考类型的功能样式,根据定义,它产生一个非左值。因此错误。

如果您希望获取临时对象的地址,您可以通过执行此操作解决限制,例如

const std::string &r = std::string("test");
&r; // this expression produces address of a temporary

只要临时存在,结果指针就会保持有效。还有其他方法可以合法获取临时对象的地址。只是你的具体方法恰好是非法的。

答案 1 :(得分:5)

当在C ++标准中使用“应该”这个词时,它意味着“必须在死亡的痛苦中” - 如果一个实现不服从这个,它就是错误的。

答案 2 :(得分:3)

在MSVC中允许使用已弃用的/ Ze(已启用扩展)选项。在之前版本的MSVC中允许使用它。它会生成一个启用了所有警告的诊断:

  

警告C4238:使用非标准扩展名:用作左值的类rvalue。

除非使用/ Za选项(强制ANSI兼容性),否则:

  

错误C2102:'&amp;'需要l值

答案 3 :(得分:1)

C ++标准实际上是对符合C ++实现的要求。在编写的地方,它是为了区分符合实现必须接受的代码和符合实现必须提供诊断的代码。

因此,在这种特殊情况下,符合条件的编译器必须在是否采用rvalue的地址时进行诊断。两个编译器都这样做,所以它们在这方面是一致的。

如果某个输入导致诊断,标准不禁止生成可执行文件,即警告是有效的诊断。

答案 4 :(得分:0)

&std::string("test");要求函数调用的返回值的地址(我们将忽略这个函数是ctor的事实无关紧要)。在您将其分配给某些内容之前,它没有地址。因此这是一个错误。

答案 5 :(得分:0)

用户定义的转化

Private Sub PowerPivotLoopSlicerPrintPDF()
Dim SC As SlicerCache
Dim SL As SlicerCacheLevel
Dim SI As SlicerItem

Set SC = ActiveWorkbook.SlicerCaches("Slicer_Kolonne1") 'Add slicer name 
'between " "
Set SL = SC.SlicerCacheLevels(1)

'c(ounter) is set to 1, ready to begin
c = 1


'Repeat the a loop until number of prints exceeds number of items in slicer
Do While c <= SC.SlicerCacheLevels.Item.Count + 1

'This makes sure that SI is the correct slicer. Needed for corrent file 
' name.
    For Each SI In SL.SlicerItems
        If SI.Selected = True Then
        SlicerverdiIndex = c
    Exit For
        End If
    Next SI


    'PRINT CODE
    Dim FName           As String
    Dim FPath           As String

    'Define file path for printed file storage
    FPath = "C:\Users\remia\Desktop\VBA\"   'Choose your filepath
    FName = SI.SourceName

    'Define WHAT to print and how to build file name
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
    FPath & "\" & FName & ".pdf", Quality:=xlQualityStandard, _
    IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
    False

    'PRINT CODE FINISHED

'Sets the slicer to the last item in the list
If SlicerverdiIndex = 1 Then
    SlicerverdiIndex = SC.SlicerCacheLevels.Item.Count + 1
End If
SC.VisibleSlicerItemsList = SL.SlicerItems(SlicerverdiIndex - 1).Name

'Adds 1 to the counter, will loop until end of slicer has been reached.
c = c + 1

Loop

End Sub

答案 6 :(得分:-1)

我不是标准专家,但对我来说这听起来确实是个错误。 g ++经常只对真正错误的事情发出警告。