boost::swap 的实现原理
2014-03-12 10:38
183 查看
在 STL 已提供
现在,对于存储大量数据的类,此方法可能不是交换数据的最有效方法,因为
您可以交换
如果上面第二和第三个选项都是有效选项,
清单 19 给出了用于交换两个数组的
清单 19. 使用 boost::swap 交换两个数组
清单 20. 使用 boost::swap 实现自定义交换
最后,模板特殊化的版本如 清单 21 中所示。
清单 21. 使用 std::swap 的模板特殊化版本
现在,让我们看看实现
22 给出了代码,它从 boost/swap.hpp 复制而来。
清单 22. boost::swap 的源代码
对于数组,调用
对于所有其他情形,会调用
清单 21)或全局
如果
原链接:http://www.oschina.net/question/129540_32439
std::swap时为什么还有必要使用
boost::swap?
std::swap的行为等效于:
template <class T> void swap ( T& a, T& b ) { T c(a); a=b; b=c; } |
swap涉及到一个
copy construction和两次赋值。另外,对于出于设计原因拥有 private 构造函数而没有复制构造函数的类,所以这种交换风格不适用。以下是
boost::swap提供的功能:
您可以交换
T类型的数组,而
std::swap不能。
boost::swap可调用具有签名
swap(T&, T&)的函数,只要存在相同的签名,且不存在默认的
copy constructor及两个赋值选项。
boost::swap可调用
std::swap的一个特殊化模板。
如果上面第二和第三个选项都是有效选项,
T必须是可构造和可赋值的副本。
清单 19 给出了用于交换两个数组的
boost::swap。
清单 19. 使用 boost::swap 交换两个数组
#include <boost/swap.hpp> #include <boost/foreach.hpp> #include <iostream> using namespace std; int main() { int a[] = {10, 20, 30, 40}; int b[] = {4, 3, 2, 1}; boost::swap(a, b); // using std::swap here won't work BOOST_FOREACH(int t, a) { cout << t << endl; } BOOST_FOREACH(int t, a) { cout << t << endl; } } |
boost::swap调用您的自定义交换例程的示例如 清单 20 中所示。
清单 20. 使用 boost::swap 实现自定义交换
#include <boost/swap.hpp> #include <iostream> using namespace std; typedef struct T { int m_data; T(int data) : m_data(data) { } } T; void swap(T& a, T& b) // custom swap routine that boost ::swap calls { cout << "In custom swap" << endl; a.m_data ^= b.m_data; b.m_data ^= a.m_data; a.m_data ^= b.m_data; } int main() { T a(30), b(10); boost::swap(a, b); cout << a.m_data << endl; cout << b.m_data << endl; } |
清单 21. 使用 std::swap 的模板特殊化版本
#include <boost/swap.hpp> #include <iostream> using namespace std; typedef struct T { int m_data; T(int data) : m_data(data) { } } T; namespace std { template< void swap<T> (T& a, T& b) { cout << "In template-specialized swap" << endl; a.m_data ^= b.m_data; b.m_data ^= a.m_data; a.m_data ^= b.m_data; } } int main() { T a(30), b(10); boost::swap(a, b); cout << a.m_data << endl; cout << b.m_data << endl; } |
boost::swap的内部原理。我们感兴趣的是如何定义
swap...for数组。清单
22 给出了代码,它从 boost/swap.hpp 复制而来。
清单 22. boost::swap 的源代码
#include <algorithm> //for std::swap #include <cstddef> //for std::size_t namespace boost_swap_impl { template<class T> void swap_impl(T& left, T& right) { using namespace std;//use std::swap if argument dependent lookup fails swap(left,right); } template<class T, std::size_t N> void swap_impl(T (& left) , T (& right) ) { for (std::size_t i = 0; i < N; ++i) { ::boost_swap_impl::swap_impl(left[i], right[i]); } } } namespace boost { template<class T1, class T2> void swap(T1& left, T2& right) { ::boost_swap_impl::swap_impl(left, right); } } |
boost::swap最终会导致调用 void
swap_impl(T (& left) , T (& right) ),因为后者也已针对数组进行了特殊化处理。查看声明
swap_impl(T (& left) , T (& right) ),这里
left和
right是具有类型
T和大小
N的数组的引用。两个数组必须具有相同的大小,否则您会获得编译错误消息。
对于所有其他情形,会调用
swap_impl(T& left, T& right)。查看
swap_impl(T& left, T& right)的定义,您会看到它调用了
swap例程。如果您拥有自己的模板特殊化的
std::swap版本(请参见
清单 21)或全局
swap例程(请参见 清单 20),将调用相同例程。否则,将调用
std::swap。
如果
boost::swap和
std::swap位于相同范围内,那么对
swap的调用将优先于
std::swap。
原链接:http://www.oschina.net/question/129540_32439
相关文章推荐
- AdaBoost--从原理到实现
- AdaBoost原理,算法实现
- boost 库 enable_shared_from_this 实现原理分析
- GBDT原理及实现(XGBoost+LightGBM)
- Boost 库 Enable_shared_from_this 实现原理分析
- chapter7 机器学习之元算法(adaboost)提高分类性能从原理到实现
- AdaBoost--从原理到实现
- Boost 库 enable_shared_from_this 实现原理分析
- boost 库 enable_shared_from_this 实现原理分析
- boost中模板函数addressof()实现原理
- boost 库 enable_shared_from_this 实现原理分析
- xgboost原理及并行实现
- Boost 库 Enable_shared_from_this 实现原理分析
- boost::bind和占位符实现的原理(from AV BOOST)
- AdaBoost--从原理到实现
- Boost 库 Enable_shared_from_this 实现原理分析
- boost 库 enable_shared_from_this 实现原理分析
- AdaBoost--从原理到实现
- boost 库 enable_shared_from_this 实现原理分析
- 高性能服务器开发之boost.asio实现原理