这是有效的 C++ 吗?

问题描述 投票:0回答:4
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;
}
c++ standards
4个回答
19
投票

不,无效。

从 5.2.2/10 [expr.call] “当且仅当结果类型是引用时,函数调用才是 lvalue

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

因此,

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


5
投票
$ g++ -Wall -o 结构 struct.cc 
struct.cc:在函数‘int main()’中:
struct.cc:21:警告:正在获取临时地址

你可能应该这样做:

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

5
投票

不,不是。

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

你的主要内容应该是这样的:

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

2
投票

如果您的函数可以接受临时变量,通常的习惯用法是传递 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;

其中为

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

© www.soinside.com 2019 - 2024. All rights reserved.