使用临时对象作为拷贝构造函数参数的问题
最近在看书遇到临时对象与const&的问题,以前一直没怎么注意这个细节,所以写了下面的程序作为测试
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
explicit A():id(++num) {
cout<<"call A():"<<id<<endl;
}
A(const A& a):id(++num) {
cout<<"call A(const A&):"<<id<<endl;
}
~A(){
cout<<"call ~A():"<<id<<endl;
}
A& operator= (const A& a) {
cout<<"operator="<<endl;
cout<<"lvalue = A:"<<id<<endl;
cout<<"rvalue = A:"<<a.id<<endl;
return *this;
}
unsigned int id;
private:
static unsigned int num;
};
unsigned int A::num = 0;
A func1() {
cout<<"in func1()"<<endl;
A a;
cout<<a.id<<endl;
cout<<"out func1()"<<endl;
return a;
}
int main() {
A a4((A()));//语句①
cout<<"a4.id = "<<a4.id<<endl;
return 0;
}
预测的结果为
call A():1
call A(const A&):2
a4.id = 2
call ~A():2
call ~A():1
但是使用GCC 4.7和VS2008进行编译,运行结果如下
call A():1
a4.id = 1
call ~A():1
如果将语句①以换成
A a4(func1())
预测的结果为
in func1()
call A():1
1
out func1()
call A(const A&):2
call ~A():1
a4.id = 2
call ~A():2
但是使用GCC 4.7的编译运行结果如下
in func1()
call A():1
1
out func1()
a4.id = 1
call ~A():1
VS2008的结果倒是符合预测
请问这是什么原因?编译器的优化问题?
另外将拷贝构造函数的const去掉后,GCC 4.7会编译错误,这符合预测。但是VS2008却没有出错,这是因为VS2008不符合标准吗?
[解决办法]
这居然是VC的扩展。
http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug
[解决办法]
1. A a4((A())); A a4(func1());
GCC应该是做了优化。
2. 另外将拷贝构造函数的const去掉后,GCC 4.7会编译错误,这符合预测。但是VS2008却没有出错,这是因为VS2008不符合标准吗?
看来VS2008对标准的支持还是不够好。LZ用VS2013试一下吧。
VS2013也一样……
1. 2013release版同gcc有优化, 而debug确实没有优化。
2. 为何可以绑定临时变量到non-const refercene?
这是vc的非标准扩展,把warning level改称W4,会有一个警告:
warning C4239: nonstandard extension used : 'initializing' : conversion from 'xxx' to 'xxx &'