Skip to content
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

Constructor not considered for lexy::dsl::nullopt #118

Open
xsebek opened this issue Jan 28, 2023 · 3 comments
Open

Constructor not considered for lexy::dsl::nullopt #118

xsebek opened this issue Jan 28, 2023 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@xsebek
Copy link

xsebek commented Jan 28, 2023

The documentation of lexy::dsl::nullopt says:

Values

A single object of the tag type lexy::nullopt. This type is implicitly convertible to any type that is optional-like by constructing a default constructible instance of it.

So when I want to create a list using lexy::dsl::opt, I would expect a constructor that takes vector to match, because vector is default constructible. But it does not. Neither does the default constructor or one taking std::nullopt_t.

The only ones that I found to match were std::optional<std::vector<...>> and lexy::dsl::nullopt:
https://godbolt.org/z/c3M7banhf

@foonathan
Copy link
Owner

Emphasis mine:

This type is implicitly convertible to any type that is optional-like by constructing a default constructible instance of it.

It is only types that are optional-like, not all default constructible types. This restriction is unfortunate, but necessary because otherwise std::optional<int>(lexy::nullopt) would be an optional containing a default-constructed int, not an empty optional.

The particular situation of dsl::opt(dsl::list(...)) is annoying, yeah. It might be worth extending to lexy::nullopt to do implicit conversions to anything that is optional-like (it requires T(), *T() and !T()) or container-like (maybe T() and T().empty()?). However, that is both a breaking change and would mean that std::optional<std::vector<T>>(lexy::nullopt) would be an optional containing an empty container, not an empty optional - which might be confusing? That being said, it matches the current behavior of std::optional<std::optional<T>>(lexy::nullopt).

@foonathan foonathan added enhancement New feature or request help wanted Extra attention is needed labels Jan 30, 2023
@xsebek
Copy link
Author

xsebek commented Jan 30, 2023

@foonathan the thing I would like to avoid is unreadable and unnecessary constructors like this one:

Group(std::optional<std::vector<int>> xs): _xs(xs ? std::move(*xs) : std::vector<int>()) {};

My understanding is that lexy needs either this one constructor or two constructors - one for the empty case and one for the list case. However, the empty case seems only satisfied with lexy::nullopt.

To me the wording of values produced by opt and nullopt seems unclear - the only thing I am sure of is that it supports std::optional.


As a side note, I just discovered opt_list in brackets/terminator, which should do what I want. Maybe linking to those as an alternative to opt(list(...)) would help? Or adding an example with a value callback. 🙂

@foonathan
Copy link
Owner

My understanding is that lexy needs either this one constructor or two constructors - one for the empty case and one for the list case. However, the empty case seems only satisfied with lexy::nullopt.

Yes, you either have single function accepting an optional<vector<T>. or two overloads, one taking lexy::nullopt and one taking vector<T>. I might change that.

To me the wording of values produced by opt and nullopt seems unclear - the only thing I am sure of is that it supports std::optional.

Yes, I will make the docs clearer.

As a side note, I just discovered opt_list in brackets/terminator, which should do what I want. Maybe linking to those as an alternative to opt(list(...)) would help? Or adding an example with a value callback. slightly_smiling_face

opt_list is essentially the same as opt(list(...)); it won't help you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants