Conversation
|
|
||
| CHECK(json(opt_null) == j_null); | ||
| CHECK(std::optional<std::string>(j_null) == std::nullopt); | ||
| CHECK_THROWS_WITH(std::optional<std::string>(j_null) == std::nullopt, |
There was a problem hiding this comment.
Why is null not converted to a nullopt here?
There was a problem hiding this comment.
See 2.b in my comments.
I agree with this view:
The reason is the template optional(U&&) constructor template, which is supposed to activate when T (int) is constructible from U and U is neither std::in_place_t nor optional, and direct-initialize T from it. And so it does, stamping out optional(foo&).
j_null is basic_json, and there is a way that basic_json can be converted to string by calling void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
There was a problem hiding this comment.
This may be a technical explanation, but as I user, when I ask to translate a JSON value to a std::optional<std::string>, then I expect this behavior:
- string values are stored as value,
nullis stored asstd::nullopt, and- all other values throw
At least this is what the code
#ifdef JSON_HAS_CPP_17
template<typename BasicJsonType, typename T>
void from_json(const BasicJsonType& j, std::optional<T>& opt)
{
if (j.is_null())
{
opt = std::nullopt;
}
else
{
opt = j.template get<T>();
}
}
#endiftries to accomplish.
This PR would fix some problems in PR#2117.
It would solve the AppVeyor compile error. Probably it is a bug in the VS compiler.
As Add conversion from/to std::optional #2117 (comment) said, I found some problems.
2.a. I used these code to detect but just found
JSON_HAS_CPP_17 = Falsein all travis jobs.Thus, All travis jobs didn't run the testcase -
TEST_CASE("std::optional"), and those all code aboutoptionalwere not compiled.I add a new travis task for c++17.
2.b. I also found the actual behavior, which would also happen in linux:
And the testcase
SECTION("null")didn't call the expected method either and raise an excepiton -"[json.exception.type_error.302] type must be object, but is null".I agree with this view:
Thus, they would not call the method
from_json(basi_json, std::option<T>)never. This is why an exception is raised inSECTION("null").Related Problem:
Different results in Clang and GCC when casting to std::optional
Why is a cast operator to std::optional ignored?
specification of std::optional constructor regarding cast operators