puch_backよりもemplace_backがいいと言われていて実験したら、push_backだとコピーコンストラクタが呼ばれないのに、emplace_backだと呼ばれる現象が発生。
結論
ムーブコンストラクタにnoexceptをつければコピーコンストラクタの代わりにムーブコンストラクタが呼ばれる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
#include <iostream> #include <vector> #include <string> #include <cassert> #include <iostream> class MyKlass { int ii_; float ff_; std::string ss_; public: MyKlass(int ii, float ff, const std::string& ss) : ii_(ii), ff_(ff), ss_(ss) { std::cout << "ctor" << std::endl; } MyKlass(const MyKlass& that) : ii_(that.ii_), ff_(that.ff_), ss_(that.ss_) { std::cout << "copy" << std::endl; } MyKlass(MyKlass&& that) : ii_(that.ii_), ff_(that.ff_), ss_(std::move(that.ss_)) { std::cout << "move" << std::endl; } ~MyKlass() { std::cout << "dtor" << std::endl; } }; // just add 'noexcept' to move ctor class MyKlassWithNoExcept { int ii_; float ff_; std::string ss_; public: MyKlassWithNoExcept(int ii, float ff, const std::string& ss) : ii_(ii), ff_(ff), ss_(ss) { std::cout << "ctor" << std::endl; } MyKlassWithNoExcept(const MyKlassWithNoExcept& that) : ii_(that.ii_), ff_(that.ff_), ss_(that.ss_) { std::cout << "copy" << std::endl; } MyKlassWithNoExcept(MyKlassWithNoExcept&& that) noexcept : ii_(that.ii_), ff_(that.ff_), ss_(std::move(that.ss_)) { std::cout << "move" << std::endl; } ~MyKlassWithNoExcept() { std::cout << "dtor" << std::endl; } }; int main() { // without noexcept { { std::vector<MyKlass> v; v.emplace_back(2, 3.14f, "jio"); // ctor std::cout << "---" << std::endl; v.emplace_back(2, 3.14f, "jio"); // ctor, copy, dtor std::cout << "---" << std::endl; v.emplace_back(2, 3.14f, "jio"); // ctor, copy, copy, dtor, dtor std::cout << "---" << std::endl; } std::cout << "------------------" << std::endl; { std::vector<MyKlass> v; v.push_back(MyKlass(2, 3.14f, "jij")); // ctor, move, dtor std::cout << "---" << std::endl; v.push_back(MyKlass(2, 3.14f, "jij")); // ctor, move, copy, dtor, dtor std::cout << "---" << std::endl; v.push_back(MyKlass(2, 3.14f, "jij")); // ctor, move, copy, copy, dtor, dtor, dtor std::cout << "---" << std::endl; } std::cout << "------------------" << std::endl; } // with noexcept { { std::vector<MyKlassWithNoExcept> v; v.emplace_back(2, 3.14f, "jio"); // ctor std::cout << "---" << std::endl; v.emplace_back(2, 3.14f, "jio"); // ctor, move, dtor std::cout << "---" << std::endl; v.emplace_back(2, 3.14f, "jio"); // ctor, move, move, dtor, dtor std::cout << "---" << std::endl; } std::cout << "------------------" << std::endl; { std::vector<MyKlassWithNoExcept> v; v.push_back(MyKlassWithNoExcept(2, 3.14f, "jij")); // ctor, move, dtor std::cout << "---" << std::endl; v.push_back(MyKlassWithNoExcept(2, 3.14f, "jij")); // ctor, move, move, dtor, dtor std::cout << "---" << std::endl; v.push_back(MyKlassWithNoExcept(2, 3.14f, "jij")); // ctor, move, move, move, dtor, dtor, dtor std::cout << "---" << std::endl; } std::cout << "------------------" << std::endl; } } |