例如:
int a = 12;
cout << typeof(a) << endl;
Run Code Online (Sandbox Code Playgroud)
预期产量:
int
Run Code Online (Sandbox Code Playgroud) 标准是否准确定义了对象移动后我可以对其做什么?我曾经认为你用移动物体做的所有事情都可以破坏它,但这还不够.
例如,采用swap标准库中定义的函数模板:
template <typename T>
void swap(T& a, T& b)
{
T c = std::move(a); // line 1
a = std::move(b); // line 2: assignment to moved-from object!
b = std::move(c); // line 3: assignment to moved-from object!
}
Run Code Online (Sandbox Code Playgroud)
显然,必须可以分配给移动的对象,否则第2行和第3行将失败.那么移动对象我还能做些什么呢?我在哪里可以找到标准中的这些细节?
(顺便说一句,为什么它T c = std::move(a);不是T c(std::move(a));第1行呢?)
我注意到std::string(真的std::basic_string是)移动赋值运算符是 noexcept.这对我来说很有意义.但后来我发现,没有一个标准集装箱(例如std::vector,std::deque,std::list,std::map)宣布其移动赋值操作符noexcept.这对我来说没什么意义.std::vector例如,A 通常实现为三个指针,并且指针当然可以移动分配而不会抛出异常.然后我想也许问题是移动容器的分配器,但std::string也有分配器,所以如果这是问题,我希望它会影响std::string.
那么为什么std::string移动赋值运算符noexcept,但标准容器的移动赋值运算符不是?
这里我特别只关心GCC编译器和运行时代码的效率。
考虑下面的代码试试我
#include <iostream>
#include <map>
char Find(const std::map<int, char>& map, int key) {
auto iter = map.find(key);
if (iter == map.end())
return 'X';
return iter->second;
}
char Find2(const std::map<int, char>& map, int key) {
return map.find(key)->second;
}
int main()
{
// part 1
std::map<int, char> x{{0,'0'}, {4,'4'}};
std::cout << Find(x, 3) << std::endl;
std::cout << Find(x, 4) << std::endl;
std::cout << (int)Find2(x, 3) << std::endl; // returns 0
std::cout << Find2(x, 4) << std::endl;
// part 2: Find2 …Run Code Online (Sandbox Code Playgroud)