【发布时间】:2012-12-14 12:35:27
【问题描述】:
使用此示例:
// 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”的副本?
【问题讨论】:
-
"但是,如果我用右值初始化 v:" 我不认为你的意思是右值
-
@JonathanWakely 这是一个“值”,一个“未命名”对象,“非左值”,一个“prvalue”。我想我的意思是右值:)如果我错了,我必须从一开始就学习 C++:P
-
好的,但是您将
"hello"和mystring()都称为“具有 r 值”,这有助于区分这些情况 -
但两者都是右值,不是吗?第一个是恒定的 r 值,第二个是可修改的 r 值,不是吗?
-
我的意思是,您可以将它们称为“字符串文字”和“右值
mystring”,以区分它们是两个非常不同的事物这一事实
标签: c++ c++11 copy move initializer-list