我的问题涉及shared_ptr
GCC 4.7.2 中的赋值运算符模板的实现,我怀疑它包含一个错误。
前提 1:C++11 标准
这是我正在谈论的赋值运算符模板的签名:
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
来自 C++11 标准(20.7.2.2.3):
“相当于 shared_ptr(r).swap(*this)
。”
换句话说,赋值运算符模板是根据构造函数模板定义的。构造函数模板的签名如下:
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
来自 C++11 标准(20.7.2.2.1):
“要求:除非 Y* 可隐式转换为 T*,否则 [...] 构造函数不得参与重载决议。”
前提 2:GCC 4.7.2 的实现:
现在 GCC 4.7.2 的构造函数模板的实现对我来说似乎是正确的(std::__shared_ptr
是的基类std::shared_ptr
):
template<typename _Tp1, typename =
typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
:
_M_ptr(__r._M_ptr),
_M_refcount()
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
但是,GCC 4.7.2 对赋值运算符模板的实现如下:
template<typename _Tp1>
__shared_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
return *this;
}
让我印象深刻的是,这个操作不是根据构造函数模板定义的,也不是swap()
. 特别是,普通赋值_M_ptr = __r._M_ptr
不会产生与类型_Tp1*
和_Tp*
通过std::is_convertible
(可以是专门的)显式检查可转换性时相同的结果。
前提 3:VC10 实现
我注意到 VC10 在这方面确实有一个更符合标准的实现,我认为这是正确的,并且在我的测试用例中表现得和我预期的一样(而 GCC 没有):
template<class _Ty2>
_Myt& operator=(const shared_ptr<_Ty2>& _Right)
{
// assign shared ownership of resource owned by _Right
shared_ptr(_Right).swap(*this);
return (*this);
}
问题:
GCC 4.7.2 的实现中是否确实存在错误shared_ptr
?我找不到有关此问题的任何错误报告。
后脚本:
如果你想问我我的测试用例是什么,我为什么要关心这个看似不重要的细节,为什么我似乎暗示我需要专攻std::is_convertible
,请在聊天中这样做。这是一个很长的故事,没有办法在不被误解的情况下总结它(及其所有令人不快的后果)。先感谢您。