std::exchange
在std::exchage
未出现之前, 我们交换两个变量的值,需要先定义一个临时的中间变量,这是经典老方法了。但是std::exchange
让我们优雅地解决这个问题。
它的主要作用是替换一个对象的值,并返回该对象的旧值。这个函数在 C++14 中引入,主要用于简化和优化代码。原型是
1 2
| template< class T, class U = T > T exchange( T& obj, U&& new_value );
|
在C++ 20里给函数加上了
constexpr
1 2 3 4
| std::string name = "Alice"; std::string new_name = "Bob";
std::string old_name = std::exchange(name, new_name);
|
还可以用于容器
1 2 3 4 5 6 7
| std::vector<int> v; std::exchange(v, {1,2,3,4}); cout << v.size() << endl; for (auto a : v) { cout << a << " "; }
|
std::exchange
在处理移动语义时非常有用。
std::exchange
是原子操作的,所以在多线程环境下是安全的,如果对程序性能有严格要求,可以换std::swap
或临时变量的方式。
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
| int multiply(int num) { return 3*num; }
vector<int> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3); vec.push_back(4); vec.push_back(5);
for(const auto &it: vec) { cout << it << endl; }
std::transform(vec.begin(), vec.end(), vec.begin(), multiply );
for(const auto &it: vec) { cout << it << endl; }
std::transform(vec.begin(), vec.end(), vec.begin(), [](int num){return 2*num; } );
for(const auto &it: vec) { cout << it << endl; }
|
再看一个配合std::back_inserter
使用的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| vector<int> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3); vec.push_back(4); vec.push_back(5);
vector<int> new_vec; std::transform(vec.begin(), vec.end(), std::back_inserter(new_vec), [](int v){ return 3*v; } );
cout << "new vec size: " << new_vec.size() << endl; for(auto it : new_vec) { cout << it << " "; }
|
运行结果
1 2
| new vec size: 5 3 6 9 12 15
|