|
188 | 188 |
|
189 | 189 | <p class="text-right"><small>
|
190 | 190 | 最終更新日時(UTC):
|
191 |
| - <span itemprop="datePublished" content="2024-07-08T07:33:21"> |
192 |
| - 2024年07月08日 07時33分21秒 |
| 191 | + <span itemprop="datePublished" content="2025-05-01T15:54:53"> |
| 192 | + 2025年05月01日 15時54分53秒 |
193 | 193 | </span>
|
194 | 194 | <br/>
|
195 | 195 | <span itemprop="author" itemscope itemtype="http://schema.org/Person">
|
196 |
| - <span itemprop="name">Akira Takahashi</span> |
| 196 | + <span itemprop="name">yoh</span> |
197 | 197 | </span>
|
198 | 198 | が更新
|
199 | 199 | </small></p>
|
@@ -233,22 +233,22 @@ <h2>概要</h2>
|
233 | 233 | <p>これはC++17に対する欠陥報告であるため、実装済みのコンパイラにおいてはC++17モード(-std=c++17を指定した場合など)でコンパイルした場合にも適用される。</p>
|
234 | 234 | <h2>この機能が必要になった背景・経緯</h2>
|
235 | 235 | <p>C++17で導入された<code>std::variant</code>には当初、<code>const char*</code>から<code>bool</code>への暗黙変換によって意図しない構築がなされるバグがあった。</p>
|
236 |
| -<p><div class="codehilite"><pre><span></span><code><span class="n">std</span><span class="o">::</span><span class="n"><a href="../../reference/variant/variant.html">variant</a></span><span class="o"><</span><span class="n"><a href="../../reference/string/basic_string.html">std::string</a></span><span class="p">,</span> <span class="kt">bool</span><span class="o">></span> <span class="n">x</span> <span class="o">=</span> <span class="s">"abc"</span><span class="p">;</span> <span class="c1">// boolを保持して構築されてしまう</span> |
| 236 | +<p><div class="codehilite"><pre><span></span><code><span class="n"><a href="../../reference/variant/variant.html">std::variant</a></span><span class="o"><</span><span class="n"><a href="../../reference/string/basic_string.html">std::string</a></span><span class="p">,</span> <span class="kt">bool</span><span class="o">></span> <span class="n">x</span> <span class="o">=</span> <span class="s">"abc"</span><span class="p">;</span> <span class="c1">// boolを保持して構築されてしまう</span> |
237 | 237 | </code></pre></div>
|
238 | 238 | </p>
|
239 | 239 | <p>この他にも構築・代入時に縮小変換が行われてしまう事から同様の問題があり、それはC++20において<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r3.html" target="_blank">P0608R3</a>によって解決された。そこでは、構築・代入時の縮小変換を禁止するとともに、<code>bool</code>に変換可能な型を<code>bool</code>に変換することを禁止することで問題に対処していた。</p>
|
240 | 240 | <p>しかしそれによって、<code>bool</code>に変換可能な<a class="cpprefjp-defined-word" data-desc="プログラム定義型。標準ライブラリの型を除く、ユーザー(プログラマ)によって定義された型のこと">ユーザー定義型</a>を<code>bool</code>値として構築・代入することができなくなった。</p>
|
241 | 241 | <p><div class="codehilite"><pre><span></span><code><span class="n"><a href="../../reference/bitset/bitset.html">std::bitset</a></span><span class="o"><</span><span class="mi">4</span><span class="o">></span> <span class="n">b</span><span class="p">(</span><span class="s">"0101"</span><span class="p">);</span>
|
242 |
| -<span class="n">std</span><span class="o">::</span><span class="n"><a href="../../reference/variant/variant.html">variant</a></span><span class="o"><</span><span class="kt">bool</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">v</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// intを保持して構築されてしまう</span> |
| 242 | +<span class="n"><a href="../../reference/variant/variant.html">std::variant</a></span><span class="o"><</span><span class="kt">bool</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">v</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// intを保持して構築されてしまう</span> |
243 | 243 | </code></pre></div>
|
244 | 244 | </p>
|
245 | 245 | <p><code>std::bitset</code>の非<code>const</code>な<code><a href="../../reference/bitset/bitset/op_at.html">operator[]</a></code>は<code>bool</code>型へ暗黙変換可能なプロキシオブジェクトを返す。</p>
|
246 | 246 | <p><code>std::variant</code>の構築・代入時に縮小変換が起こることを検出して防止することはライブラリレベルで可能だったが、ポインタ型から<code>bool</code>への変換を縮小変換として扱うということはライブラリレベルでは実装できなかったため<code>bool</code>への変換全体を禁止せざるを得ず、このような問題が発生していた。</p>
|
247 | 247 | <p>これらの問題の解決のために、ポインタ型から<code>bool</code>型への変換は縮小変換であると規定することになった。これによって、<code>std::variant</code>の構築・代入時のポインタ型から<code>bool</code>型への変換は縮小変換の一種として検出され禁止されるようになり、上記のコードは意図どおりに動作するようになる。</p>
|
248 |
| -<p><div class="codehilite"><pre><span></span><code><span class="n">std</span><span class="o">::</span><span class="n">variant</span><span class="o"><</span><span class="n"><a href="../../reference/string/basic_string.html">std::string</a></span><span class="p">,</span> <span class="kt">bool</span><span class="o">></span> <span class="n">x</span> <span class="o">=</span> <span class="s">"abc"</span><span class="p">;</span> <span class="c1">// <a href="../../reference/string/basic_string.html">std::string</a>を保持して構築</span> |
| 248 | +<p><div class="codehilite"><pre><span></span><code><span class="n"><a href="../../reference/variant/variant.html">std::variant</a></span><span class="o"><</span><span class="n"><a href="../../reference/string/basic_string.html">std::string</a></span><span class="p">,</span> <span class="kt">bool</span><span class="o">></span> <span class="n">x</span> <span class="o">=</span> <span class="s">"abc"</span><span class="p">;</span> <span class="c1">// <a href="../../reference/string/basic_string.html">std::string</a>を保持して構築</span> |
249 | 249 |
|
250 | 250 | <span class="n"><a href="../../reference/bitset/bitset.html">std::bitset</a></span><span class="o"><</span><span class="mi">4</span><span class="o">></span> <span class="n">b</span><span class="p">(</span><span class="s">"0101"</span><span class="p">);</span>
|
251 |
| -<span class="n">std</span><span class="o">::</span><span class="n">variant</span><span class="o"><</span><span class="kt">bool</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">v</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// boolを保持して構築</span> |
| 251 | +<span class="n"><a href="../../reference/variant/variant.html">std::variant</a></span><span class="o"><</span><span class="kt">bool</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">v</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// boolを保持して構築</span> |
252 | 252 | </code></pre></div>
|
253 | 253 | </p>
|
254 | 254 | <p><code>{}</code>初期化では縮小変換が禁止されているためこれは破壊的変更となるが、そのような変換は多くの場合バグの可能性が高いこと、MSVCは非リテラルのポインタから<code>bool</code>への変換を縮小変換として扱っていたことなどから、影響は少なくメリットの方が大きいと判断されたようだ。</p>
|
|
0 commit comments