使用此示例:
// test.cpp
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
class mystring : public string { public:
mystring() = default;
mystring(const char* c) : string(c) {}
mystring(mystring& m) : string(m) { cout << "Reference" << endl; }
mystring(mystring const & m) : string(m) { cout << "Const reference" << endl; }
mystring(mystring&& m) : string(move(m)) { cout << "Move" << endl; }
};
int main() {
mystring a;
vector<mystring> v{ a };
}
输出是:
$ g++ --version | grep "g++"
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
$ g++ -std=c++11 -fno-elide-constructors test.cpp
$ ./a.out
Reference
Move
Const reference
但是,如果我用 r 值初始化 v:
vector<mystring> v{"hello"};
输出是:
$ g++ -std=c++11 -fno-elide-constructors test.cpp
$ ./a.out
Const reference
这意味着,没有副本。使用 r 值:
vector <mystring> v{mystring()};
输出:
$ g++ -std=c++11 -fno-elide-constructors test.cpp
$ ./a.out
Move
Move
Const reference
我不明白两件事:
- 为什么使用非原始字符串执行第二次移动(在第一次复制/移动之前)?
- 为什么使用原始字符串,不执行“mystring”的副本?