我试图通过阅读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> {};
的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
,结果与is_assignable<T&, T&&>::value
相同,否则为false
。
我注意到的第一件事是libc ++将const
应用于第二个模板参数,这似乎不正确,因为移动赋值运算符采用非const rvalue。 libstdc ++也使用__is_referenceable
,它遵循标准的措辞,但libc ++没有。 libc ++使用add_lvalue_reference
和add_rvalue_reference
是否涵盖了这个要求,它们都自己强制执行__is_referenceable
?
我非常感谢每个项目选择他们的解决方案的原因!
答案 0 :(得分:8)
谢谢!知道作者为什么可能添加了
const
,然后呢?
我最好的猜测是暂时的(希望)精神错乱:
- )
我删除了const
并运行了当前的单元测试,没有任何失败。
答案 1 :(得分:6)
对于任何可引用的东西,这两个实现都做同样的事情,因为libc ++中无关的is_copy_assignable
没有意义但也无害。
(从差异来看,它对我来说当然看起来像是暂时的疯狂:)似乎是void
的(错误)实现的C&amp; P问题。)
对于任何不可引用的东西(即cv false_type
或可恶的函数类型),libstdc ++返回add_{l,r}value_reference
。
在libc ++中,const
将其保持不变(这取决于后期C ++ 14的问题解决方案)。在顶部放置const
不会对AFT产生任何影响,并为void
y类型添加is_assignable
。
然后我们转到declval<T>() = declval<U>()
,其中SFINAE测试T == U == some AFT
或T == some void type
和U = some const-qualified void type
的格式false_type
。在所有情况下,表达形式都不正确(以SFINAE友好的方式),因此我们得到#include <ncurses.h>
int main (int argc, char *argv[]) {
int ch, c;
initscr ();
cbreak ();
noecho ();
while (ch != 'q') {
switch (c = getch ()) {
case 'a':
ch = 'b';
break;
case 'b':
ch = 'c';
break;
case 'c':
ch = 'd';
break;
default:
ch = c;
break;
}
printw ("%c", ch);
}
endwin ();
return (0);
}
。
这两者是等价的。
答案 2 :(得分:5)
__is_referenceable
是一个非标准的内部libstdc ++例程。 (这并不意味着它很糟糕,只是因为我不希望libc ++使用它)。此外,&#34;是可引用的&#34;概念出现的时间远远晚于is_move_assignable
。
__is_referenceable
有助于处理&#34;恶劣的功能&#34 ;;像int (*) (double) &&
这样的东西。
看起来我需要编写更多测试: - )