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

call visitor with no argument if variant is uninitialized #93

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lightmare
Copy link
Contributor

If called on uninitialized variant, apply_visitor leads to dispatcher calling get<T> with the last alternative type, which throws.

This PR changes the behaviour so that the dispatcher either

  • throws with more helpful message "apply_visitor on uninitialized variant", or
  • calls the visitor with no arguments, if that is possible

I also considered default-constructing the result type, instead of throwing, if the visitor cannot be called with no argument. That could work in some cases (e.g. when visitor extracts some value and default-constructed is okay; or when it applies some transformation and returns void), but could be very surprising in others, so I didn't include this "feature".

@springmeyer
Copy link
Contributor

/cc @artemp @joto

@lightmare
Copy link
Contributor Author

D'oh! GCC 4.7 doesn't fail to substitute decltype(void(declval<F>()())) when F doesn't have operator()(), and then wants to call it... 💥 No idea how to fix that atm

@springmeyer
Copy link
Contributor

GCC 4.7 is not a critical compiler to support. I've been wondering if we should drop support for it. Because its c++11 support is pretty marginal anyway.

@artemp
Copy link
Contributor

artemp commented Feb 25, 2016

@lightmare - I like the general idea around 'no_init, thanks! Ideally would be nice not to require writingno-op` code at all. I'll review in over coming days and maybe we'll do a point release ? /cc @springmeyer @joto

@lightmare
Copy link
Contributor Author

Ideally would be nice not to require writingno-op` code at all.

Yes, that is possible if R (the return type inferred from the first_type) is default-constructible. It's hard to imagine real usage that would rely on the visitor either being called with a value, or exception thrown.

A contrived example could be made from the unit test. auto a = 12345 / apply_visitor(total_size(), v) -- currently this throws bad_variant_access if v is uninitialized. If we default-constructed the result, it would divide by zero.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants