C++11 中的 type_traits, 改变了一些约定成俗的名字:
我们经常使用的 has_trivial_destructor, 变成了is_trivially_destructible, 现在已有不少编译器实现了 has_trivial_destructor, (std, std::tr1). 如此, 要写可移植的代码, 要么使用 tr1, 要么使用 boost, 鉴于 tr1 出现的比 boost 更晚, boost 一般是首选, 而新的编译器往往自带了 tr1, 而 boost 要另外安装.........
We think in general, but we live in details. 一个简单的 type_traits, 也需要这么多折腾.
以下是标准关于 type_traits 更新的详细列表
is_constructible | is_nothrow_constructible | |
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
Furthermore, as noted in GB 92 for the "nothrow" traits, the definitions have become redundant and confusing. This redundancy and confusion actually extends to nearly all of these traits, and in some cases actually leads to incorrect definitions, or at the very least, a lack of self-consistency among the traits. For example, as specified in the current Working Draft:
typedef char Array[3]; is_constructible<Array, const Array&>::value == false has_copy_constructor<Array, const Array&>::value == true
With our proposed clarifying names, we wish foris_copy_constructible<T>to have the exact same behavior asis_constructible<T, const T&>. So we have adjusted the definitions of theis_*_constructibletraits to be simple synonyms foris_constructibleand similarly for the "nothrow" variants. E.g.:
template <class T> struct has_nothrow_copy_constructoris_nothrow_copy_constructible;has_trivial_copy_constructor<T>::valueistrueoris_nothrow_constructible<U, const U&>::valueistrue, whereUisremove_all_extents<T>::type.
is_nothrow_constructible<T, const T&>::valueistrue.Tshall be a complete type, (possiblycv-qualified)void, or an array of unknown bound.
This formulation makes it much easier to get the definitions correct. I.e. what it means to be "nothrow constructible" is defined in exactly one place (the definition ofis_nothrow_constructible). The other "nothrow constructible" traits reuse this definition as much as possible, with no repetition.
However we note that we can not currently apply this formula to the "trivially constructible" traits, nor tois_trivially_destructible, nor to any of the assignable traits. The problem is the lack ofis_destructible(FI 18), lack ofis_trivially_constructible, and the lack of generalized assignable traits. We strongly feel that this lack of completeness will inevitably lead to situations where programmers will not be able to query or assert properties of types necessary to the correct operation of their code. For example a container is likely to assert that a contained type have a non-throwing destructor. Lack of this property leads to the container's destructor becoming a source of memory leaks.
Therefore we propose the following 6 new traits to complete the suite of traits:
is_constructible | is_nothrow_constructible | is_trivially_constructible |
is_default_constructible | is_nothrow_default_constructible | is_trivially_default_constructible |
is_copy_constructible | is_nothrow_copy_constructible | is_trivially_copy_constructible |
is_move_constructible | is_nothrow_move_constructible | is_trivially_move_constructible |
is_destructible | is_nothrow_destructible | is_trivially_destructible |
is_assignable | is_nothrow_assignable | is_trivially_assignable |
is_copy_assignable | is_nothrow_copy_assignable | is_trivially_copy_assignable |
is_move_assignable | is_nothrow_move_assignable | is_trivially_move_assignable |
We address GB 91 in the definition of the newly introducedis_assignabletrait, usingdeclvalas suggested. All of the rest of the assignable traits reuse this definition without repetition.
In addition we wish to address GB 50 and GB 51 in this paper because the topic is intimately related to the definition of move construction and move assignment and subsequently theis_move_constructibleandis_move_assignabletraits.
The following list shows the current usages of the terms "move-construct" and "move-assign" in the library. While some occurrences are purely descriptive usages of these words, most of them refer to what the type traitsis_move_constructible<T>andis_move_assignable<T>stand for. The list omits to enumerate all usages of these terms within the definition ofpairandtuples, because those will be completely replaced by another paper (N3140).
Table 42, entry:X::propagate_on_container_move_assignment
true_typeonly if an allocator of type Xshould be moved when the client container is move-assigned.
Table 96 — Allocator-aware container requirements (continued), entry "a = rv":
All existing elements of aare either move assigned to or destroyed.