让我们考虑以下 Microsoft Visual C++(Microsoft Visual Studio 2012 RC,版本 11.0.50522.1 RCREL)中自定义数组的类模板。
/*C++11 switch-on*/
#include <iostream>
template <typename element, unsigned int size>
class array
{
private:
element data[size];
public:
array(){}
~array(){}
array(const array & other)(){}
element & operator [](unsigned int i)
{
if(i<size)
return data[i];
else
throw std::runtime_error("Out of boundary");
}
}
请注意,构造函数、析构函数和复制构造函数被定义为什么都不做。一个普通的打印函数定义如下
/*printing*/
template <typename element, unsigned int size>
void print(test::array<element, size> & content)
{
unsigned int i=0;
for(std::cout<<"["<<content[i++];i<size;std::cout<<content[i++])
std::cout<<",";
std::cout<<"]"<<std::endl;
}
当程序运行以下主要
int main(int argc, char * argv[])
{
array<int, 3> a;
/* uniform initialization is not supported yet
* so we bother iterating to assign to initialize
* a to [1,2,3]
*/
for(int i=0;i<3;i++)
a[i]=i+1;
/*copy*/
auto b=a;
/*move*/
auto c=std::move(a);
/*change in a*/
a[0]=0;
print<int, 3>(a);
print<int, 3>(b);
print<int, 3>(c);
return 0;
}
根据编译优化,输出结果会有所不同。特别是,如果我编译并运行
/Od 打开
a =[0,2,3]
b =[1470797225,-2,9185596]
c =[0,2620008,9186761]
/O1、/O2 或 /Ox 打开
a =[0,2,3]
b =[0,2,3]
c =[0,2,3]
现在我明白了
- /Od 打开
- b与a不同,因为复制构造函数在调用时什么也不做
- c与a不同,因为复制构造函数在调用时什么也不做。但是根据移动语义, a 中数组数据中元素的变化也反映到c上。所以a[0]==c[0]==0。
但我不明白为什么a,b和c在优化开关打开时都相等。我可能认为 Microsoft C++ 编译器用确实移动的复制构造函数代替了不执行任何操作的复制构造函数,但我只是不确定。