2013-11-09 24 views
6

标准C++类型,如int或焦有构建函数,这样就可以有这样的表达式:通过引用传递一个匿名可变

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

您的'func2'行不应该编译(出于与第一个相同的原因)。 – Mat

+0

'void main()'是非标准的。 –

+0

在适当的警告级别下,您将得到'警告C4239:使用非标准扩展名:'参数':从'STRUCT'转换为'STRUCT&';非const引用只能绑定到左值。你应该使用'/ W4'。 –

回答

2

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

相反,你必须选择:从C++ 03

void func1(int&& i){} 

void func1(const int& i){} 

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

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

5

看来你使用的MS VC++编译器有这样的bug :)你必须绑定临时对象与const引用。例如,您可能写

const int &ri = 10; 

但你可能不写

int &ri = 10; 

同样是有效的用户定义的类型。

const STRUCT &rs = STRUCT(10); 

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

在C++中,一个匿名临时对象始终是一个right-value.To接受权值作为参数,可以:

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

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