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 ++コンパイラは、何もしないコピーコンストラクタを移動するコピーコンストラクタに置き換えると思うかもしれませんが、それについてはよくわかりません。