-
Notifications
You must be signed in to change notification settings - Fork 887
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
Conversion with default values #357
Comments
Thanks you for sending the issue. I think that convert_if_not_nil() is a good idea. However, I don't understand yet which case is Boost.Optional is not good enough. We can use 'as' with #include <msgpack.hpp>
#include <iostream>
int main() {
{
std::map<std::string, int> m;
m.emplace("ABC", 42);
msgpack::zone z;
msgpack::object o(m, z);
auto opt = o.as<boost::optional<std::map<std::string, int>>>();
if (opt) {
std::cout << "optional has a value." << std::endl;
auto it = opt->find("ABC");
if (it != opt->end()){
std::cout << it->first << ":" << it->second << std::endl;
}
}
}
{
msgpack::object o;
auto opt = o.as<boost::optional<std::map<std::string, int>>>();
if (opt) {
}
else {
std::cout << "optional doesn't have a value." << std::endl;
}
}
} Output
Do you mean even if we can't use Boost libraries, we can use convert_if_not_nil() instead of that? |
That would be one way to see it. I think that boost::optional will always provide a feasible way to achieve the desired outcome. I think, however, that it's overly verbose and not overly practical when the non-optional type should be kept after unpacking. In addition to a Boost-less environment, these are the use cases where I believe boost::optional isn't the optimal solution:
In such cases, boost::optional will generally require one or two more lines of code than the equivalent using convert_if_not_null(). (Try rephrasing my last example box with boost::optional if you want to check, with a requirement of keeping a non-optional type after unpacking.) In addition to saving lines of code, unpacking directly into the target object also saves one copy or move (instead of object -> boost::optional -> target). So I while think it's mostly a convenience method rather than a necessity, I think it is one that benefits readability and compactness for common use cases. |
Possible alternative names for convert_if_not_nil(): convert_if_exists(), convert_if_has_value(). (The naming is a trade-off here: I think convert_if_not_nil() describes most accurately what it's doing, but the other two phrase it without negation which is also a good thing. I'm undecided which one is a better trade-off.) |
Thanks for the clarification. I understand. I think convert_if_not_nil is fine too :) |
msgpack::object provides
as<>()
andconvert(T)
functions to extract values. In order to handle fields that are potentially nil, newer msgpack revisions also provide support forboost::optional
, so I can write code like this:There is still an unnecessary verbosity when dealing with default values:
I can see two potential accessor method patterns that can help simplify this code:
All of the above have in common that
object
is only used once, which can sometimes help prevent creation of a temporary msgpack::object variable and just continue from a msgpack::object function result instead. Which can make the code even more compact (while retaining readability) compared to the baseline.While the
get_or()
suffers from possible template mismatches and can't be used forif (...) foo->set(...);
style clauses,convert_if_not_nil()
handles both well and seems like an improvement without drawbacks. Here is an implementation (note that it will still throw if the object exists but contains an unexpected type):How would you feel about this method being added to msgpack::object?
The text was updated successfully, but these errors were encountered: