标准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
}
答案 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 ++编译器。您不能将临时右值绑定到非常量左值引用。这是规则。 clang和gcc都不会为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”只能接受左值引用传递的参数。所以传递匿名参数是错误的。