Dav*_*own 17 c++ libstdc++ c++11 libc++ c++14
我正在尝试通过阅读C++ 14标准以及libc ++和libstdc ++的源代码来更深入地理解C++.type_traits两者之间的各种项目的实施情况各不相同,特别是is_move_assignable,我试图弄清楚哪些项目"更正确".
的libc ++:
template <class _Tp> struct is_move_assignable
: public is_assignable<typename add_lvalue_reference<_Tp>::type,
const typename add_rvalue_reference<_Tp>::type> {};
Run Code Online (Sandbox Code Playgroud)
的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>
{ };
Run Code Online (Sandbox Code Playgroud)
标准规定:
对于可引用类型
T,结果与is_assignable<T&, T&&>::value否则相同false.
我注意到的第一件事是libc ++适用const于第二个模板参数,这似乎不正确,因为移动赋值运算符采用非const rvalue.libstdc ++也使用__is_referenceable,遵循标准的措辞,但libc ++没有.是通过规定的libc ++的使用覆盖add_lvalue_reference和add_rvalue_reference,这既加强__is_referenceable自己?
我真的很感激为什么每个项目都选择他们的解决方案!
谢谢!知道作者为什么会添加
const,然后呢?
我最好的猜测是暂时的(希望)精神错乱:
;-)
我删除了const并运行了当前的单元测试,没有任何失败.
对于任何可引用的东西,这两个实现都做同样的事情,因为constlibc ++中的无关是没有意义的,但也是无害的.
(从差异来看,它对我来说当然看起来像是暂时的疯狂:)似乎是(错误的)实施的C&P问题is_copy_assignable.)
对于任何不可引用的东西(即cv void或abominable函数类型),libstdc ++都会返回false_type.
在libc ++中,add_{l,r}value_reference返回它不变(这取决于后期C++ 14的问题解决方案).洒const在顶部对AFT没有任何作用,并const为voidy类型添加了一个.
然后,我们去is_assignable,这SFINAE检验的良好性declval<T>() = declval<U>(),对于任何一个T == U == some AFT或T == some void type和U = some const-qualified void type.在所有情况下,表达形式都不正确(以SFINAE友好的方式),所以我们false_type回来了.
两者是等价的.
__is_referenceable是一个非标准的内部libstdc ++例程.(这并不意味着它很糟糕,只是我不希望libc ++使用它).此外,"可参考"概念出现的时间要晚得多is_move_assignable.
__is_referenceable处理"可恶的功能"时的帮助; 比如int (*) (double) &&.
看起来我需要写更多测试:-)