////
Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)

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)

Official repository: https://github.com/boostorg/json
////

= 不抛异常的转换 对于不希望抛出异常的场景，Boost.JSON 还提供了 &lt;<ref_value_to>&gt; 的不抛异常版本，即函数模板 &lt;<ref_try_value_to>&gt;。它返回 {ref_result}，这是一个特化的变体类型，要么持有转换得到的值，要么持有 {ref_error_code}。</ref_try_value_to></ref_value_to>

[NOTE]
对于 &lt;<ref_value_from>&gt;; 没有对应的不抛异常版本。这仅仅是因为我们尚未遇到需要 &lt;<ref_value_from>&gt; 向调用者报告错误的情况。</ref_value_from></ref_value_from>

该库为 &lt;<ref_value_to>&gt; 所支持的所有类型类别均提供了不抛异常的转换。如果用户希望将其用于自定义类型，则需要提供如下形式的 `tag_invoke` 重载：</ref_value_to>

``` result_for<t, value="">::type tag_invoke( const try_value_to_tag&lt; T &gt;&amp;, const value&amp; ); ```</t,>

对于 &lt;<custom_conversions>&gt; 节中所述的 `ip_address` 类，该重载可能如下所示：</custom_conversions>

[source]
----
include::../../../test/snippets.cpp[tag=snippet_nothrow_1,indent=0]
----

该重载使我们能够将 `ip_address` 与 &lt;<ref_try_value_to>&gt; 一起使用。</ref_try_value_to>

[source]
----
include::../../../test/snippets.cpp[tag=snippet_nothrow_2,indent=0]
----

如果将 &lt;<ref_try_value_to>&gt; 与某种类型搭配使用，而该类型不存在本节中所描述的这种形式的 `tag_invoke` 重载函数，但存在用于 &lt;<ref_value_to>&gt; 形式的那种重载函数，那么库仍会尝试进行转换。它会使用抛出异常的重载函数，并尝试将任何抛出的异常转换为 {ref_error_code}。不过需要注意的是，这种方式可能比专门的重载函数要慢一些。</ref_value_to></ref_try_value_to>

反之亦然：如果存在适用于&lt;<ref_try_value_to>&gt; 的 tag_invoke 重载，但没有适用于 &lt;<ref_value_to>&gt; 的重载，那么调用 &lt;<ref_value_to>&gt; 时会转而调用不抛异常的重载，随后根据返回的 {ref_error_code} 构造一个 {ref_system_error} 并抛出。由于存在上述回退机制，建议用户在计划使用 &lt;<ref_try_value_to>&gt; 时，优先提供本节所述的不抛异常重载，而非抛异常的重载。</ref_try_value_to></ref_value_to></ref_value_to></ref_try_value_to>
