-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add noexcept json::value("key", default) method variant? #1546
Comments
Thanks for the proposal and sharing a concrete implementation! I understand you do not want an exception to be thrown. However, I am not sure whether it would be safe to mark your code |
Technically, it would only require |
Thanks for the quick response! I had try to wrap my head around noexcept - but still a bit unsure. this seems to work as expected for me (msvc 141):
edit - I should add that I'm using this overload for const char *
|
No, because For example, this compiles but will do nasty things:
|
Thanks! That makes sense. Going back to the copy version, it seems to me @jaredgrubb you're right about ValueType only needing to be nothrow-copy-able. This seems to work correctly in my tests: template<class ValueType, typename std::enable_if<std::is_convertible<nlohmann::json::basic_json_t, ValueType>::value, int>::type = 0 >
inline ValueType json_value( const nlohmann::json& j, const typename nlohmann::json::object_t::key_type& key, const ValueType& default_value )
noexcept( std::is_nothrow_copy_constructible<ValueType>::value )
{
try {
// if key is found, return value and given default value otherwise
nlohmann::json::const_iterator it = j.find( key );
if( it != j.end() ) {
return *it;
}
} catch( ... ) { }
return default_value;
} Using the class foo
{
public:
foo() {}
~foo() {}
foo( const foo & f ) { throw; }
};
inline void from_json( const nlohmann::json& j, foo& f ) { }
inline void to_json( nlohmann::json & j, const foo & f ) { }
int main()
{
nlohmann::json j = {
{ "null", nullptr },
{ "foo", foo() }
};
// value null - return default
int i = 0;
try {
i = json_value( j, "null", 1 );
} catch( ... ) {
std::cout << "threw at `i = json_value(j, \"null\", 1);`" << std::endl;
}
std::cout << "i = " << i << std::endl;
// foo copy throws
try {
foo f = json_value( j, "foo", foo() );
} catch( ... ) {
std::cout << "threw at `f = json_value( j, \"foo\", foo() );`" << std::endl;
}
// key not found - return default (throwing copy)
try {
foo f = json_value( j, "no foo", foo() );
} catch( ... ) {
std::cout << "threw at `f = json_value( j, \"no foo\", foo() );`" << std::endl;
}
} prints
This behavior makes more sense to me than
should be wrapped in a try block anyway. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
the
json::value("key", default)
method is helpful, but allowing it to throw adds quite a bit of redundant try {} catch {} boilerplate - this can be especially onerous when e.g. loading config from sparse or error-prone json, where every value() call must be wrapped in a try{} block (in which case, why not just use the .at() method?)A secondary noexcept value() function would be really helpful in this case - like
json::value_safe("key", default)
.rather than
In my code I'm using the utility function:
The text was updated successfully, but these errors were encountered: