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

P0196R2 -- none() and nested optional #14

Open
akrzemi1 opened this issue Oct 19, 2016 · 4 comments
Open

P0196R2 -- none() and nested optional #14

akrzemi1 opened this issue Oct 19, 2016 · 4 comments
Labels

Comments

@akrzemi1
Copy link
Contributor

The examples in the paper show how I can disambiguate the type of none in the following case:

optional<unique_ptr<int>> o1 = none<optional>;
assert (!o1);

optional<unique_ptr<int>> o2 = none<unique_ptr>;
assert (o2);

But I cannot figure out, if it helps me with initializing an optional optional:

optional<optional<int>> o1 = none<optional<int>>; // possbile?
assert (o1);

optional<optional<int>> o2 = none<optional<optional<int>>>; // possible?
assert (!o2);

Does this paper allow me to initialize an optional at any 'depth'?

@viboes
Copy link
Owner

viboes commented Apr 23, 2017

Sorry I missed this issue.

Currently both contains none.
Note that

  template <class TC>
  using none_type_t = decltype(nullable::none<TC>());

So if the following was possible

optional<optional<int>> o1 = none<optional<int>>;
assert (o1);

this would mean that none_type_t<optional<int>> would be optional<int>, which we don't want.

Maybe none_type should be defined by specialization then. I'll comeback to you if I can change this.

This works however

    optional<optional<int>> x = optional<int>(none()) ;
    assert(x);
    optional<optional<int>> x = none<optional>();
    assert(!x);

@viboes
Copy link
Owner

viboes commented Apr 23, 2017

After some changes

  // definition by default
  template <class TC>
  struct none_type {
    using type = decltype(nullable::none<TC>());
  };
  template <class TC>
  using none_type_t = typename none_type<TC>::type;

and

  template <class T>
  struct none_type<optional<T>> {
    using type = nullopt_t;
  };

  template <>
  struct traits<optional<_t>> : traits_pointer_like {
    static constexpr
    nullopt_t none() { return nullopt; }

    template <class U>
    static constexpr
    nullopt_t deref_none(U &&)
      { return nullopt; }
  };

  template <class T>
  struct traits<optional<T>> : traits_pointer_like {
    static constexpr
    optional<T> none() { return nullopt; }

    template <class U>
    static constexpr
    nullopt_t deref_none(U &&)
      { return nullopt; }

  };

we can have what you requested as possible

optional<optional<int>> o1 = none<optional<int>>();
assert(o1);

optional<optional<int>> o2 = none<optional<optional<int>>>();
assert(! o2);

optional<optional<int>> o3 = none<optional>();
assert(! o3);

My question is if this is the behavior we want.

@akrzemi1
Copy link
Contributor Author

I am not qualified to answer whether we want it or not. My observation was that the proposal did not clearly describe what happens in such case. If you say, "such use case is intentionally not addressed by the proposal" I am satisfied with this statement.

viboes added a commit that referenced this issue Apr 29, 2017
@viboes viboes added the bug label May 9, 2017
@viboes
Copy link
Owner

viboes commented Jun 4, 2017

I've rolled back these changes.

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

No branches or pull requests

2 participants