这是有效的C ++吗?

时间:2009-10-31 16:41:31

标签: c++ standards compiler-construction

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;
}

4 个答案:

答案 0 :(得分:19)

不,它无效。

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

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

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

答案 1 :(得分:5)

$ g++ -Wall -o stuct struct.cc 
struct.cc: In function ‘int main()’:
struct.cc:21: warning: taking address of temporary

你可能应该这样做:

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

答案 2 :(得分:5)

不,不是。

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

你的主要应该是这样的:

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

答案 3 :(得分: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+的调用返回临时{{1}}。

相关问题