通过引用传递匿名变量

时间:2013-11-09 12:02:20

标签: c++ pass-by-reference anonymous

标准C ++类型(如int或char)具有ctors,因此您可以使用以下表达式:

int a = int(67); // create anonymous variable and assing it to variable a
int b(13);       // initialize variable b
int(77);         // create anonymous variable

用户定义的类型(结构或类)也可以这样做:

struct STRUCT
{
  STRUCT(int a){}
};

STRUCT c = STRUCT(67);
STRUCT d(13);
STRUCT(77);

问题是:为什么我们可以通过引用匿名结构或类实例传递,但不能传递标准类型?

struct STRUCT
{
  STRUCT(int a){}
};

void func1(int& i){}
void func2(STRUCT& s){}
void func3(int i){}
void func4(STRUCT s){}

void main()
{
  //func1(int(56));  // ERROR: C2664
  func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference
  func3(int(46));    // OK: anonymous int is created then assigned to a parameter
  func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter
}

3 个答案:

答案 0 :(得分:5)

您似乎正在使用具有此类错误的MS VC ++编译器。:)您必须使用const引用绑定临时对象。例如,你可以写

const int &ri = 10;

但你可能不会写

int &ri = 10;

同样适用于用户定义的类型。

const STRUCT &rs = STRUCT( 10 );

STRUCT &rs = STRUCT( 10 ); // the compiler shall issue an error.

答案 1 :(得分:3)

如果您的编译器允许这样做,那么它不是标准兼容的C ++编译器。您不能将临时右值绑定到非常量左值引用。这是规则。 clanggcc都不会为func2(STRUCT(65));编译该代码。

相反,你有其他选择:

void func1(int&& i){}

void func1(const int& i){}

来自C ++ 03的遗产:对非const类型(int &i)的(左值)引用应该能够更改参数然后传递临时对象(例如56)是不合逻辑的因为它不会改变。对const类型(const int &i)的引用应该只是将值视为只读,然后传递一个临时值,例如52是合法的。

在C ++ 11中,您可以通过&&引用非const临时对象。

答案 2 :(得分:0)

在c ++中,匿名临时对象始终是右值。要接受右值作为参数,您可以:

1).void foo1(TYPE); //路过值
2).void foo2(const TYPE&); //通过const引用传递
3).void foo3(TYPE&&); //在c ++ 11中,通过右值引用

你的“func3”和“func4”接受一个按值传递的参数,没关系 但是,“func1”和“func2”只能接受左值引用传递的参数。所以传递匿名参数是错误的。