【问题标题】:Is this valid C++?这是有效的 C++ 吗?
【发布时间】:2026-01-07 19:10:02
【问题描述】:
struct SomeStruct
{
  int a; 
  int b;
};

SomeStruct someFn( int init )
{
  SomeStruct ret = { init, init };
  //...
  return ret;
}

void someFn2( SomeStruct* pStruct )
{
  // ..
}

int main( )
{
  someFn2( &someFn(32) );
  return 0;
}

【问题讨论】:

  • 对我来说看起来很有效,但你为什么不编译它并找出来?
  • 定义“barfs”。您可以使用 -Wall (或编译器上的等效项)进行编译并查看是否有任何警告吗?如何发布您收到的确切错误消息。
  • @Daniel“它可以编译”和“它对我有用”并不是很好的有效性衡量标准。
  • 埃文:你应该把它添加到你的问题中。

标签: c++ standards compiler-construction


【解决方案1】:

不,无效。

From 5.2.2/10 [expr.call] "一个函数调用是一个左值当且仅当结果类型是一个引用。

从 5.3.1/2 [expr.unary.op] “操作数应为左值或 qualified-id”。

因此,

someFn(32) 不是 lvalue,因为 SomeStruct 不是引用,您将其用作需要左值的 & 的操作数。

【讨论】:

    【解决方案2】:
    $ g++ -Wall -o stuct struct.cc struct.cc:在函数“int main()”中: struct.cc:21:警告:获取临时地址

    你可能应该这样做:

    int main( )
    {
      SomeStruct s = someFn(32);
      someFn2(&s);
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      不,不是。

      您只能在左值上使用 &。 SomeFn(32) 不是左值。

      你的主要应该是这样的:

      int main( )
      {
        SomeStruct s;
        s = someFn(32);
        someFn2(&s);
        return 0;
      }
      

      【讨论】:

        【解决方案4】:

        如果您的函数可以接受临时变量,通常的习惯用法是传递 const 引用而不是指针。

        #include<iostream>
        
        struct SomeStruct {
            int a;
            int b;
        
            ~SomeStruct() {
                std::cout << "SomeStruct destroyed" << std::endl;
            }
        };
        
        SomeStruct someFn ( int init )
        {
            SomeStruct ret = { init, init };
            return ret;
        }
        
        void someFn2 ( SomeStruct* pStruct )
        {
            std::cout << "someFn2 called" << std::endl;
        }
        
        void someFn2 ( const SomeStruct& someStruct )
        {
            std::cout << "someFn2 called" << std::endl;
        }
        
        int main( )
        {
            someFn2 ( &someFn ( 32 ) ); // warning - taking address of temporary
            someFn2 ( someFn ( 32 ) ); // no warning - safe in non-broken compilers
            return 0;
        }
        

        输出

        someFn2 called
        SomeStruct destroyed
        someFn2 called
        SomeStruct destroyed
        

        IIRC,“未损坏”编译器集不包括 Visual C++ 2003 或更早版本。

        stl 中这个成语的一个例子是:

        string a = "red";
        string b = " apple";
        string c = a + b;
        

        c 调用std::string(const std::string&amp;) 构造函数,并从调用std::string::operator+ 返回临时std::string

        【讨论】:

          最近更新 更多