The effect of calling any member function other than the destructor, the
move-assignment operator, 
share, or 
valid on a 
future object for which
valid() == false
is undefined
.[
Note 2: 
It is valid to move from a future object for which 
valid() == false. — 
end note]
Recommended practice: Implementations should detect this case and throw an object of type
future_error with an error condition of 
future_errc::no_state. namespace std {
  template<class R>
  class future {
  public:
    future() noexcept;
    future(future&&) noexcept;
    future(const future&) = delete;
    ~future();
    future& operator=(const future&) = delete;
    future& operator=(future&&) noexcept;
    shared_future<R> share() noexcept;
    
    see below get();
    
    bool valid() const noexcept;
    void wait() const;
    template<class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
    template<class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
  };
}