C++03と11
次のソースをコンパイルして実行する。move関係はC++03のときはコメントアウトする。
#include <iostream> #include <vector> struct S { int i; S () { std::cout << "default constructor" << std::endl; } S (const int i) : i(i) { std::cout << "constructor: i=" << i << std::endl; } S (const S & s) : i(s.i) { std::cout << "copy constructor: i=" << i << std::endl; } S (const S && s) : i(s.i) { std::cout << "move constructor: i=" << i << std::endl; } ~S () { std::cout << "destructor: i=" << i << std::endl; } S & operator = (const S & s) { i = s.i; std::cout << "operator=(&): i=" << i << std::endl; return *this; } S & operator = (const S && s) { i = s.i; std::cout << "operator=(&&): i=" << i << std::endl; return *this; } }; void printv (std::vector<S> & v) { for (std::vector<S>::iterator it = v.begin(); it != v.end(); ++it) { std::cout << it->i << ", "; } std::cout << std::endl; } int main () { //std::vector<S> v = {1,2,3}; // initializer-list std::vector<S> v(3); v[0] = S(1); v[1] = S(2); v[2] = S(3); printv(v); std::vector<S>::iterator it = v.begin(); std::advance(it, 1); v.erase(it); printv(v); }
コンパイラのバージョン。
$ g++ --version g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang++ --version Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0) Target: x86_64-pc-linux-gnu Thread model: posix
結果
$ g++ -std=c++03 -W -Wall -pedantic vec.cc $ ./a.out default constructor copy constructor: i=6303208 copy constructor: i=6303208 copy constructor: i=6303208 destructor: i=6303208 constructor: i=1 operator=(&): i=1 destructor: i=1 constructor: i=2 operator=(&): i=2 destructor: i=2 constructor: i=3 operator=(&): i=3 destructor: i=3 1, 2, 3, operator=(&): i=3 destructor: i=3 1, 3, destructor: i=1 destructor: i=3 $ clang++ -std=c++03 -W -Wall -pedantic vec.cc $ ./a.out default constructor copy constructor: i=4202384 copy constructor: i=4202384 copy constructor: i=4202384 destructor: i=4202384 constructor: i=1 operator=(&): i=1 destructor: i=1 constructor: i=2 operator=(&): i=2 destructor: i=2 constructor: i=3 operator=(&): i=3 destructor: i=3 1, 2, 3, operator=(&): i=3 destructor: i=3 1, 3, destructor: i=1 destructor: i=3 $ g++ -std=c++11 -W -Wall -pedantic vec.cc $ ./a.out default constructor default constructor default constructor constructor: i=1 operator=(&&): i=1 destructor: i=1 constructor: i=2 operator=(&&): i=2 destructor: i=2 constructor: i=3 operator=(&&): i=3 destructor: i=3 1, 2, 3, operator=(&&): i=3 destructor: i=3 1, 3, destructor: i=1 destructor: i=3 $ clang++ -std=c++11 -W -Wall -pedantic vec.cc $ ./a.out default constructor default constructor default constructor constructor: i=1 operator=(&&): i=1 destructor: i=1 constructor: i=2 operator=(&&): i=2 destructor: i=2 constructor: i=3 operator=(&&): i=3 destructor: i=3 1, 2, 3, operator=(&&): i=3 destructor: i=3 1, 3, destructor: i=1 destructor: i=3
結構違うもんやな(小並感)
元々、std::vector
vのコンストラクタの挙動が03と11で異なるのは意外。03の方はstd::vector
規格と実装を見ながら比較できればいいんだけど、ちょっと時間がないのでここまで。