Blame view

3rdparty/boost_1_81_0/libs/conversion/doc/conversion.qbk 8.02 KB
977ed18d   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  [/
      Copyright 2016 Mikhail Maximov.
      Copyright Antony Polukhin, 2020-2022.
  
      Distributed under the Boost Software License, Version 1.0. (See accompanying
      file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
  ]
  
  [article The Conversion Library
      [quickbook 1.6]
      [compatibility-mode 1.5]
      [id conversion]
      [version 1.7]
      [authors [Stroustrup, Bjarne], [Abrahams, Dave], [Rasin, Boris], [Polukhin, Antony]]
      [copyright 2001 Beman Dawes, 2014-2022 Antony Polukhin]
      [license
          Distributed under the Boost Software License, Version 1.0.
          (See accompanying file LICENSE_1_0.txt or copy at
          [@http://www.boost.org/LICENSE_1_0.txt])
      ]
      [source-mode c++]
  ]
  
  [/ QuickBook Document version 1.5 ]
  [/ Dec, 2016 ]
  
  [section Description]
  
  The Conversion Library improves program safety and clarity by performing
  otherwise messy conversions. It includes cast-style function templates designed 
  to complement the C++ Standard's built-in casts.
  
  To reduce coupling, particularly to standard library IOStreams, 
  the Boost Conversion Library is supplied by several headers:
  
  # The [@boost:boost/polymorphic_cast.hpp boost/polymorphic_cast.hpp] header
    provides [link polymorphic_cast `polymorphic_cast<>`] and
    [link polymorphic_downcast `polymorphic_downcast<>`]
    to perform safe casting between polymorphic types.
  # The [@boost:boost/polymorphic_pointer_cast.hpp boost/polymorphic_pointer_cast.hpp] header
    provides [link polymorphic_pointer_cast `polymorphic_pointer_cast<>`] and
    [link polymorphic_pointer_cast `polymorphic_pointer_downcast<>`]
  # The [@boost:boost/implicit_cast.hpp boost/implicit_cast.hpp] header provides `implicit_cast<>` 
    to perform implicit casts only (no down-cast, no void*->T*, no U->T if T has only explicit constructors for U).
  # The [@boost:boost/lexical_cast.hpp boost/lexical_cast.hpp] header 
    provides [@boost:doc/libs/release/libs/lexical_cast/ `lexical_cast<>`] general literal text conversions, such as an `int` represented as a `string`, or vice-versa. 
  
  [endsect]
  
  [section Polymorphic casts]
  Pointers to polymorphic objects (objects of classes which define at
  least one virtual function) are sometimes downcast or crosscast.
  Downcasting means casting from a base class to a derived class.
  Crosscasting means casting across an inheritance hierarchy diagram, such
  as from one base to the other in a [^Y] diagram hierarchy.
  
  Such casts can be done with old-style casts, but this approach is
  never to be recommended. Old-style casts are sorely lacking in type
  safety, suffer poor readability, and are difficult to locate with search
  tools.
  
  [#polymorphic_downcast]
  [section polymorphic_downcast]
  
  The C++ built-in `static_cast` can be used for efficiently
  downcasting pointers to polymorphic objects, but provides no error
  detection for the case where the pointer being cast actually points to
  the wrong derived class. The `polymorphic_downcast` template retains
  the efficiency of `static_cast` for non-debug compilations, but for
  debug compilations adds safety via an `assert()` that a `dynamic_cast`
  succeeds.
  
  A `polymorphic_downcast` should be used for
  downcasts that you are certain should succeed. Error checking is
  only performed in translation units where `NDEBUG` is
  not defined, via
  ```
      assert( dynamic_cast<Derived>(x) == x )
  ```
  where `x` is the source pointer.  This approach
  ensures that not only is a non-zero pointer returned, but also
  that it is correct in the presence of multiple inheritance.
  Attempts to crosscast using `polymorphic_downcast` will
  fail to compile.
  
  [warning Because `polymorphic_downcast` uses `assert()`, it
  violates the One Definition Rule (ODR) if `NDEBUG` is inconsistently
  defined across translation units. See ISO Std 3.2]
  
  [h4 Example:]
  ```
      #include <boost/polymorphic_cast.hpp>
      ...
      class Fruit { public: virtual ~Fruit(){}; ... };
      class Banana : public Fruit { ... };
      ...
      void f( Fruit * fruit ) {
        // ... logic which leads us to believe it is a Banana
        Banana * banana = boost::polymorphic_downcast<Banana*>(fruit);
        ...
      }
  ```
  [endsect]
  
  [#polymorphic_cast]
  [section polymorphic_cast]
  
  The C++ built-in `dynamic_cast` can be used for downcasts and
  crosscasts of pointers to polymorphic objects, but error notification in
  the form of a returned value of 0 is inconvenient to test, or worse yet,
  easy to forget to test. The throwing form of `dynamic_cast`, which
  works on references, can be used on pointers through the ugly expression
  `&dynamic_cast<T&>(*p)`, which causes undefined
  behavior if `p` is `0`. The `polymorphic_cast`
  template performs a `dynamic_cast` on a pointer, and throws an
  exception if the `dynamic_cast` returns 0.
  
  For crosscasts, or when the success of a cast can only be known at runtime, 
  or when efficiency is not important, `polymorphic_cast` is preferred.
  
  The C++ built-in `dynamic_cast` must be used to cast references rather than pointers.
  It is also the only cast that can be used to check whether a given interface is supported; in that case a return of 0 isn't an error condition.
  
  [endsect]
  
  
  [#polymorphic_pointer_cast]
  [section polymorphic_pointer_cast]
  While `polymorphic_downcast` and `polymorphic_cast` work with built-in pointer types only,
  `polymorphic_pointer_downcast` and `polymorphic_pointer_cast` are more generic versions
  with support for any pointer type for which the following expressions would be valid:
  
  For `polymorphic_pointer_downcast`:
  ```
      static_pointer_cast<Derived>(p);
      dynamic_pointer_cast<Derived>(p);
  ```
  For `polymorphic_pointer_cast`:
  ```
      dynamic_pointer_cast<Derived>(p);
      !p; // conversion to bool with negation
  ```
  
  This includes C++ built-in pointers, `std::shared_ptr`,
  `boost::shared_ptr`, `boost::intrusive_ptr`, etc.
  
  
  [h4 Example:]
  ```
      #include <boost/polymorphic_pointer_cast.hpp>
  
      class Fruit { public: virtual ~Fruit(){} };
      class Banana : public Fruit {};
  
      // Use one of these:
      typedef Fruit* FruitPtr;
      typedef std::shared_ptr<Fruit> FruitPtr;
      typedef boost::shared_ptr<Fruit> FruitPtr;
      typedef boost::intrusive_ptr<Fruit> FruitPtr;
  
      void f(FruitPtr fruit) {
        // ... logic which leads us to believe it is a banana
        auto banana = boost::polymorphic_pointer_downcast<Banana>(fruit);
        ...
      }
  ```
  
  [endsect]
  
  [endsect]
  
  [section Synopsis]
  ```
      namespace boost {
  
      // Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
      // Returns: dynamic_cast<Derived>(x)
      template <class Derived, class Base>
      inline Derived polymorphic_cast(Base* x);
  
      // Effects: assert( dynamic_cast<Derived>(x) == x );
      // Returns: static_cast<Derived>(x)
      template <class Derived, class Base>
      inline Derived polymorphic_downcast(Base* x);
  
      // Effects: assert( dynamic_cast<Derived>(&x) == &x );
      // Returns: static_cast<Derived>(x)
      template <class Derived, class Base>
      inline Derived polymorphic_downcast(Base& x);
  
      // Throws: std::bad_cast if ( dynamic_pointer_cast<Derived>(x) == 0 )
      // Returns: dynamic_pointer_cast<Derived>(x)
      template <class Derived, class Base>
      inline auto polymorphic_pointer_cast(Base x);
  
      // Effects: assert( dynamic_pointer_cast<Derived>(x) == x );
      // Returns: static_pointer_cast<Derived>(x)
      template <class Derived, class Base>
      inline auto polymorphic_pointer_downcast(Base x);
  
      }
  ```
  [endsect]
  
  
  [section History]
  `polymorphic_cast` was suggested by Bjarne Stroustrup in "The C++ Programming Language".
  
  `polymorphic_downcast` was contributed by [@http://www.boost.org/people/dave_abrahams.htm Dave Abrahams].
  
  `polymorphic_pointer_downcast` was contributed by [@http://www.boost.org/people/boris_rasin.htm Boris Rasin]
  and `polymorphic_pointer_cast` by Antony Polukhin.
  
  `polymorphic_downcast` overload for references was contributed by Julien Delacroix.
  
  An old `numeric_cast` that was contributed by [@http://www.boost.org/people/kevlin_henney.htm Kevlin Henney]
  is now superseded by the [@boost:numeric_conversion/doc/html/html/boost_numericconversion/improved_numeric_cast__.html Boost Numeric Conversion Library]
  [endsect]