2016-10-11 33 views
17

我想通过阅读C++ 14标准以及libC++和libstdC++的源文件来深入理解C++。各种type_traits项目的执行情况在两者之间有所不同,尤其是is_move_assignable,我试图找出哪些是“更正确的”。libC++ vs libstdC++ std :: 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> {}; 

的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> 
    { }; 

标准状态:

对于可引用类型T,相同的结果​​,否则false

我注意到的第一件事是,libc中++应用const到第二个模板参数,这看起来不正确,因为此举赋值运算符需要一个非const右值。 libstdC++也使用__is_referenceable,它遵循标准的措辞,但libC++不符合。 libC++使用add_lvalue_referenceadd_rvalue_reference是否满足这个要求,它们都自己执行__is_referenceable

我真的很感谢每个项目为什么选择他们的解决方案!

+1

对于任何可引用的参数,'const'是无意义的(当应用于引用类型时,cv-qualifiers被忽略)。 –

+0

@ T.C。谢谢!任何想法为什么作者可能添加了'const',那么? –

+8

通常情况下你可以得到这样的响应时间:https://github.com/llvm-mirror/libcxx/commit/a75b75f514c5c92c8ad8d304b76a01a979b6134c :-) –

回答

6

对于任何可参考的两种实现方式做同样的事情,因为在libc中的外来const ++是没有意义的,但也无害。

(从差异来看,它肯定看起来像一时失去理智给我:)似乎是一个C & P问题从(错误)的实施is_copy_assignable

对于任何非可引用(即, cv void或可恶的函数类型),libstdC++返回false_type

在libC++中,add_{l,r}value_reference将其返回为无变化(这取决于后置C++ 14的问题解决方案)。在顶部喷洒const对于AFT不做任何处理,并且为void y类型添加const

然后,我们去is_assignable,这SFINAE检验的declval<T>() = declval<U>()的良好性,对于任何一个T == U == some AFTT == some void typeU = some const-qualified void type。在所有情况下,这个表达方式都是不健全的(用SFINAE友好的方式),所以我们回到false_type

这两者是等效的。

5

__is_referenceable是一个非标准的内部libstdC++例程。 (这并不意味着它不好,只是我不希望libC++使用它)。此外,“可参考”概念比is_move_assignable晚得多。

__is_referenceable有助于处理“恶劣的功能”;例如int (*) (double) &&

看起来我需要编写更多的测试,:-)

+0

libC++实际上为'add_lvalue_reference'的实现定义了'__is_referenceable', add_rvalue_reference',但我不确定是否通过使用'add_rvalue_reference'隐式地应用'__is_referenceable'将始终产生与libstdC++显式使用'__is_referenceable'相同的行为。对不起,如果没有意义。 –

+0

'(*)'不应该在那里:) –

相关问题