libc++ vs libstdc++ std::is_move_assignable:哪个最正确?
libc++ vs libstdc++ std::is_move_assignable: Which is the most correct?
我试图通过阅读 C++14 标准以及 libc++ 和 libstdc++ 的源代码来更深入地了解 C++。各种 type_traits
项目的实现在两者之间有所不同,特别是 is_move_assignable
,我试图弄清楚它们中的哪一个是 "more correct."
libc++:
template <class _Tp> struct is_move_assignable
: public is_assignable<typename add_lvalue_reference<_Tp>::type,
const typename add_rvalue_reference<_Tp>::type> {};
libstdc++:
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
struct __is_move_assignable_impl;
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, false>
: public false_type { };
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, true>
: public is_assignable<_Tp&, _Tp&&>
{ };
template<typename _Tp>
struct is_move_assignable
: public __is_move_assignable_impl<_Tp>
{ };
标准规定:
For a referenceable type T
, the same result as is_assignable<T&, T&&>::value
, otherwise false
.
我注意到的第一件事是 libc++ 将 const
应用于第二个模板参数,这似乎不正确,因为移动赋值运算符采用非 const 右值。 libstdc++也使用__is_referenceable
,遵循标准的写法,但libc++没有。 libc++ 对 add_lvalue_reference
和 add_rvalue_reference
的使用是否涵盖了这一要求,它们都强制执行 __is_referenceable
?
如果能深入了解每个项目为何选择他们的解决方案,我将不胜感激!
Thanks! Any idea why the authors might have added const
, then?
我最好的猜测是暂时的(希望)精神错乱:
;-)
我删除了 const
和 运行 当前的单元测试并且没有失败。
__is_referenceable
是一个非标准的内部 libstdc++ 例程。 (这并不意味着它不好,只是我不希望 libc++ 使用它)。此外,"is referenceable" 概念的出现比 is_move_assignable
晚得多。
__is_referenceable
有助于处理 "abominable functions"; int (*) (double) &&
.
之类的东西
看来我需要编写更多测试:-)
对于任何可引用的内容,这两个实现做同样的事情,因为 libc++ 中无关的 const
没有意义但也无害。
(从差异来看,这对我来说肯定是暂时的精神错乱:)似乎是 is_copy_assignable
的(错误)实现的 C&P 问题。)
对于任何不可引用的东西(即 cv void
或可恶的函数类型),libstdc++ returns false_type
.
在 libc++ 中,add_{l,r}value_reference
returns 它没有变化(这取决于晚于 C++14 的问题解决方案)。在顶部洒一个 const
对 AFT 没有任何作用,并为 void
y 类型添加一个 const
。
然后我们转到 is_assignable
,SFINAE 测试 declval<T>() = declval<U>()
的良构性,对于 T == U == some AFT
或 T == some void type
和 U = some const-qualified void type
。在所有情况下,表达式都是错误的(以 SFINAE 友好的方式),所以我们得到 false_type
返回。
两者是等价的
我试图通过阅读 C++14 标准以及 libc++ 和 libstdc++ 的源代码来更深入地了解 C++。各种 type_traits
项目的实现在两者之间有所不同,特别是 is_move_assignable
,我试图弄清楚它们中的哪一个是 "more correct."
libc++:
template <class _Tp> struct is_move_assignable
: public is_assignable<typename add_lvalue_reference<_Tp>::type,
const typename add_rvalue_reference<_Tp>::type> {};
libstdc++:
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
struct __is_move_assignable_impl;
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, false>
: public false_type { };
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, true>
: public is_assignable<_Tp&, _Tp&&>
{ };
template<typename _Tp>
struct is_move_assignable
: public __is_move_assignable_impl<_Tp>
{ };
标准规定:
For a referenceable type
T
, the same result asis_assignable<T&, T&&>::value
, otherwisefalse
.
我注意到的第一件事是 libc++ 将 const
应用于第二个模板参数,这似乎不正确,因为移动赋值运算符采用非 const 右值。 libstdc++也使用__is_referenceable
,遵循标准的写法,但libc++没有。 libc++ 对 add_lvalue_reference
和 add_rvalue_reference
的使用是否涵盖了这一要求,它们都强制执行 __is_referenceable
?
如果能深入了解每个项目为何选择他们的解决方案,我将不胜感激!
Thanks! Any idea why the authors might have added
const
, then?
我最好的猜测是暂时的(希望)精神错乱:
;-)
我删除了 const
和 运行 当前的单元测试并且没有失败。
__is_referenceable
是一个非标准的内部 libstdc++ 例程。 (这并不意味着它不好,只是我不希望 libc++ 使用它)。此外,"is referenceable" 概念的出现比 is_move_assignable
晚得多。
__is_referenceable
有助于处理 "abominable functions"; int (*) (double) &&
.
看来我需要编写更多测试:-)
对于任何可引用的内容,这两个实现做同样的事情,因为 libc++ 中无关的 const
没有意义但也无害。
(从差异来看,这对我来说肯定是暂时的精神错乱:)似乎是 is_copy_assignable
的(错误)实现的 C&P 问题。)
对于任何不可引用的东西(即 cv void
或可恶的函数类型),libstdc++ returns false_type
.
在 libc++ 中,add_{l,r}value_reference
returns 它没有变化(这取决于晚于 C++14 的问题解决方案)。在顶部洒一个 const
对 AFT 没有任何作用,并为 void
y 类型添加一个 const
。
然后我们转到 is_assignable
,SFINAE 测试 declval<T>() = declval<U>()
的良构性,对于 T == U == some AFT
或 T == some void type
和 U = some const-qualified void type
。在所有情况下,表达式都是错误的(以 SFINAE 友好的方式),所以我们得到 false_type
返回。
两者是等价的