当我不需要在整个当前范围内徘徊的命名对象时,便一直使用匿名变量。

我需要使用一个函数-在我的控制范围之外-该函数将指针作为参数并且不进行NULL检查。我希望能够传递一个匿名变量的地址(因为我不在乎写在解引用地址上的值),但是却遇到编译错误。下面的简化示例...

#include <iostream>

void ptrFunc( const int* p )
{
  if ( p )
  {
    std::cout << "*p == " << *p << std::endl;
  }
}

void refFunc( const int& i )
{
  std::cout << "(ref)i == " << i << std::endl;
}

void valueFunc( int i )
{
  std::cout << "i == " << i << std::endl;
}

int main( int argc, char* argv[] )
{
  valueFunc( int() );   // This is fine.
  refFunc( int() );     // This is also fine.
  ptrFunc( &(int()) );  // This doesn't compile.
}

...生成此编译错误:
>g++ -g main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:25:19: error: lvalue required as unary '&' operand
   ptrFunc( &(int()) );  // This doesn't compile.
                   ^
>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

编译器错误易读:使用地址运算符需要一个左值。但是我想知道社区是否可以帮助我理解此限制的原因。在我看来,我的尝试使用可能合理合法,因为匿名变量的生命周期取决于分号,即在ptrFunc()的生命周期内它是“有效的”。

我考虑了由于其寿命缩短而允许使用指向匿名变量的指针是否被视为“危险”。但是,如果将指针用于任何用途,即使是用于左值或堆分配的对象,也会遇到相同的问题:如果有人卡在任何指针上,则始终存在指向无效内存的危险。指针的使用本质上取决于仔细的编码,并且我认为这种尝试的用例在这方面没有特别的不同。

我很好奇这背后的原理。谢谢。

我还尝试了吗?

尝试使用gcc-4.9.2在线编译示例代码,以达到相同的效果;因此,此问题不是来自过时的编译器的限制/错误。

最佳答案



在这种情况下,可以。一般来说,没有。

引用导致临时对象的生存期延长。指针没有。也就是说,给定:

int main() {
    const int & a = 1;
    int && b = 2;
    const int * c = &static_cast<const int &>(3); // don't do this
    return a + b - *c;
}

引用ab继续引用有效对象。指针c无效,并且生存期扩展规则没有合理的方法可以适用于指针,而指针的含义没有重大的根本变化。对于引用而言,它是可行的,因为引用是一种新的(与C语言相比)语言功能,并且作为一种新的语言功能,毫无疑问使它们保持不变。指针有很多使用它们的现有代码,这些代码将因规则的更改而失效。

08-27 22:16