6

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

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

3 回答 3

7

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

相反,您有其他选择:

void func1(int&& i){}

void func1(const int& i){}

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

在 C++11 中,您可以通过&&.

于 2013-11-09T12:10:46.420 回答
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.
于 2013-11-09T12:18:24.707 回答
0

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

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

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

于 2013-11-09T12:42:21.070 回答