关于 boost::swap 的问题
Posted
技术标签:
【中文标题】关于 boost::swap 的问题【英文标题】:Question on boost::swap 【发布时间】:2011-05-24 18:39:19 【问题描述】:关于boost::swap
的几个问题。请参考下面的代码,它基本上是来自boost/swap.hpp
的剪切粘贴。我指的是库版本 1.43.0。
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)[N], T (& right)[N])
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
声明为template <typename T1, typename T2>
而在其余代码中都处理相同的类型?
如果我定义自己的全局函数void swap(T&, T&)
,我发现它是从swap_impl(T& left, T& right)
调用的全局函数。这不是冲突,因此不是错误条件,因为swap_impl
也使用了已定义交换的namespace std
?
【问题讨论】:
【参考方案1】:-
这使得它不像
std::swap
那样专门化,因此当 std::swap
和 boost::swap
都在范围内时,您不会出现过载歧义错误(std::swap
将优先)。
不,在重载解析期间非模板总是优先于模板,因此命名空间范围的非模板 swap
将优先于 boost::swap
和 std::swap
(命名空间范围的模板 @987654332 @ 为 UDT 重载 - 认为是部分专业化的,但不是真的..)。请注意,与 std::swap
不同,boost::swap
是明确编写的,以利用 ADL。
以下是 C++03 标准对这两点的看法 – [over.match.best] (§13.3.3/1):
如下定义ICSi(
如果F
):F
是静态成员函数,ICS1(F
) 被定义为 ICS1(F
) 既不好也不坏对于任何函数G
,都比 ICS1(G
),而且对称地,ICS1(G
) 既不比 ICS 好也不差1(F
);否则, 让 ICSi(F
) 表示将列表中的第 i 个参数转换为 i-可行函数的参数F
。 13.3.3.1 定义了隐式转换序列,13.3.3.2 定义了一个隐式转换序列比另一个更好或更差的转换序列意味着什么。鉴于这些定义,如果对于所有参数 i,ICSi(
对于某些参数j,ICSj(F1
) 的转换序列并不比 ICS 差i(F2
),然后F1
) 是比 ICSj(F2
) 更好的转换序列,或者,如果不是这样,F1
是非模板函数,F2
是函数模板特化,或者,如果不是,F1
和F2
是函数模板特化,根据 14.5.5.2 中描述的偏序规则,F1
的函数模板比F2
的模板更特化,或者,如果不是这样,李> 上下文是通过用户定义的转换(参见 8.5、13.3.1.5 和 13.3.1.6)和从F1
的返回类型到目标类型(即实体被初始化)是比从F2
的返回类型到目标类型的标准转换序列更好的转换序列。
【讨论】:
@jam:+1。能否请您指出 C++ 参考标准部分,该部分讨论了非模板优于模板代码的优先级? @ildjarn:恐怕你的笔记是under contention。我也认为是这样,但也许不是。 @GMan:感谢您的提醒。 :-] 回答您的问题后,我将相应地编辑我的答案。不过,如果你是对的,而且 C++11 没有像 Boost 那样解决这个问题,这当然是一种耻辱,尤其是考虑到实现是多么微不足道。 但为什么是using namespace std;
而不是using std::swap;
?
@L.F. : 但这与问题无关,这些问题非常具体。 ;-] 关于该主题有很多现有问题,例如this 和this。以上是关于关于 boost::swap 的问题的主要内容,如果未能解决你的问题,请参考以下文章