Document number: N3148=10-0138
Date: 2010-10-14
Author:J. Daniel Garcia
Project: Programming Language C++, Library Working Group
Reply to: josedaniel.garcia@uc3m.es

N3148 - throw() becomes noexcept (Version 2)

During the Rapperswil meeting the Library Working Group decided to change the empty dynamic exception specifications in the librrary to the noexcept specification in the standard library. There was unanimous consent about this change.

This paper presents proposed wording for this set of changes.

The paper addresses National Body comments CH 16 and GB 60.

Identified changes

All changes in this paper are against N3126. This paper proposes the following changes: The exception specifications for class auto_ptr have not been updated as it is a deprecated class. The same is apllied to set_unexpected.

Revision history

Since N3114 the following changes have been made:

Acknowledgments

I would like to thank Alisdair Meredith for guiding me in the writing of the first version of this paper and providing me with hints to improve it.

Daniel Krügler and David Svoboda provided very useful feedback for the final version of this paper.

Wording

3.7.4 Dynamic storage duration

After p. 2
...
void operator delete(void*) throw()noexcept;
void operator delete[](void*) throw()noexcept;

17.6.4.11 Restrictions on exception handling

1 Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph or its exception-specification (15.4). An implementation may strengthen the exception-specification for a non-virtual function by removing listed exceptions adding a non-throwing noexcept-specification.195

Delete footnote 195:

195) That is, an implementation of the function will have an explicit exception-specification that lists fewer exceptions than those specified in this International Standard. It may not, however, change the types of exceptions listed in the exception-specification from those specified, nor add others.

Modify footnote 196:

196) That is, the C library functions can all be treated as if they have a throw() exception-specificationare noexcept. This allows implementations to make performance optimizations based on the absence of exceptions at runtime.

18.3.1.1 Class template numeric_limits


namespace std {
  template<class T> class numeric_limits {
  public:
    static constexpr bool is_specialized = false;
    static constexpr T min() throw()noexcept { return T(); }
    static constexpr T max() throw()noexcept { return T(); }
    static constexpr T lowest() throw()noexcept { return T(); }
    static constexpr int digits = 0;
    static constexpr int digits10 = 0;
    static constexpr int max_digits10 = 0;
    static constexpr bool is_signed = false;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact = false;
    static constexpr int radix = 0;
    static constexpr T epsilon() throw()noexcept { return T(); }
    static constexpr T round_error() throw()noexcept { return T(); }
    static constexpr int min_exponent = 0;
    static constexpr int min_exponent10 = 0;
    static constexpr int max_exponent = 0;
    static constexpr int max_exponent10 = 0;
    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss = false;
    static constexpr T infinity() throw()noexcept { return T(); }
    static constexpr T quiet_NaN() throw()noexcept { return T(); }
    static constexpr T signaling_NaN() throw()noexcept { return T(); }
    static constexpr T denorm_min() throw()noexcept { return T(); }
    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = false;
    static constexpr bool is_modulo = false;
    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };
  template<class T> class numeric_limits<const T>;
  template<class T> class numeric_limits<volatile T>;
  template<class T> class numeric_limits<const volatile T>;
}

18.3.1.2 numeric_limits members

Before p.1:

static constexpr T min() throw()noexcept;

After p.3:

static constexpr T max() throw()noexcept;

After p.5:

static constexpr T lowest() throw()noexcept;

After p.23:

static constexpr T epsilon() throw()noexcept;

After p.25:

static constexpr T round_error() throw()noexcept;

After p.46:

static constexpr T infinity() throw()noexcept;

After p.48:

static constexpr T quiet_NaN() throw()noexcept;

After p.50:

static constexpr T signaling_NaN() throw()noexcept;

After p.52:

static constexpr T denorm_min() throw()noexcept;

18.3.1.5 numeric_limits specializations

2 [Example:


namespace std {
  template<> class numeric_limits<float> {
  public:
    static constexpr bool is_specialized = true;
    inline static constexpr float min() throw()noexcept { return 1.17549435E-38F; }
    inline static constexpr float max() throw()noexcept { return 3.40282347E+38F; }
    inline static constexpr float lowest() throw()noexcept { return -3.40282347E+38F; }
    static constexpr int digits = 24;
    static constexpr int digits10 = 6;
    static constexpr int max_digits10 = 9;
    static constexpr bool is_signed = true;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact = false;
    static constexpr int radix = 2;
    inline static constexpr float epsilon() throw()noexcept { return 1.19209290E-07F; }
    inline static constexpr float round_error() throw()noexcept { return 0.5F; }
    static constexpr int min_exponent = -125;
    static constexpr int min_exponent10 = - 37;
    static constexpr int max_exponent = +128;
    static constexpr int max_exponent10 = + 38;
    static constexpr bool has_infinity = true;
    static constexpr bool has_quiet_NaN = true;
    static constexpr bool has_signaling_NaN = true;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss = false;
    inline static constexpr float infinity() throw()noexcept { return ...; }
    inline static constexpr float quiet_NaN() throw()noexcept { return ...; }
    inline static constexpr float signaling_NaN() throw()noexcept { return ...; }
    inline static constexpr float denorm_min() throw()noexcept { return min(); }
    static constexpr bool is_iec559 = true;
    static constexpr bool is_bounded = true;
    static constexpr bool is_modulo = false;
    static constexpr bool traps = true;
    static constexpr bool tinyness_before = true;
    static constexpr float_round_style round_style = round_to_nearest;
  };
}

-- end example]

3 The specialization for bool shall be provided as follows:


namespace std {
  template<> class numeric_limits<bool> { 
  public:
    static constexpr bool is_specialized = true;
    static constexpr bool min() throw()noexcept { return false; }
    static constexpr bool max() throw()noexcept { return true; }
    static constexpr bool lowest() throw()noexcept { return false; }
    static constexpr int digits = 1;
    static constexpr int digits10 = 0;
    static constexpr int max_digits10 = 0;
    static constexpr bool is_signed = false;
    static constexpr bool is_integer = true;
    static constexpr bool is_exact = true;
    static constexpr int radix = 2;
    static constexpr bool epsilon() throw()noexcept { return 0; }
    static constexpr bool round_error() throw()noexcept { return 0; }
    static constexpr int min_exponent = 0;
    static constexpr int min_exponent10 = 0;
    static constexpr int max_exponent = 0;
    static constexpr int max_exponent10 = 0;
    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss = false;
    static constexpr bool infinity() throw()noexcept { return 0; }
    static constexpr bool quiet_NaN() throw()noexcept { return 0; }
    static constexpr bool signaling_NaN() throw()noexcept { return 0; }
    static constexpr bool denorm_min() throw()noexcept { return 0; }
    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = true;
    static constexpr bool is_modulo = false;
    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };
}

18.6 Dynamic memory management

1 The header <new> defines several functions that manage the allocation of dynamic storage in a program. It also defines components for reporting storage management errors.

Header <new> synopsis


namespace std {
  class bad_alloc;
  class bad_array_new_length;
  struct nothrow_t {};
  extern const nothrow_t nothrow;
  typedef void (*new_handler)();
  new_handler set_new_handler(new_handler new_p) throw()noexcept;
}

void* operator new(std::size_t size) throw(std::bad_alloc);
void* operator new(std::size_t size, const std::nothrow_t&) throw()noexcept;
void operator delete(void* ptr) throw()noexcept;
void operator delete(void* ptr, const std::nothrow_t&) throw()noexcept;
void* operator new[](std::size_t size) throw(std::bad_alloc);
void* operator new[](std::size_t size, const std::nothrow_t&) throw()noexcept;
void operator delete[](void* ptr) throw()noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) throw()noexcept;
void* operator new (std::size_t size, void* ptr) throw()noexcept;
void* operator new[](std::size_t size, void* ptr) throw()noexcept;
void operator delete (void* ptr, void*) throw()noexcept;
void operator delete[](void* ptr, void*) throw()noexcept;

18.6.1.1 Single-object forms

After p.4

void* operator new(std::size_t size, const std::nothrow_t&) throw()noexcept;

After p.9

void operator delete(void* ptr) throw()noexcept;

After p.15

void operator delete(void* ptr, const std::nothrow_t&) throw()noexcept;

18.6.1.2 Array forms

After p.4

void* operator new[](std::size_t size, const std::nothrow_t&) throw()noexcept;

After p.8

void operator delete[](void* ptr) throw()noexcept;

After p.13void operator delete[](void* ptr, const std::nothrow_t&) throw()noexcept;

18.6.1.3 Placement forms

After p.1

void* operator new(std::size_t size, void* ptr) throw()noexcept;

After p.4

void* operator new[](std::size_t size, void* ptr) throw()noexcept;

After p.6

void operator delete(void* ptr, void*) throw()noexcept;

After p.9

void operator delete[](void* ptr, void*) throw()noexcept;

18.6.2.1 Class bad_alloc


namespace std {
  class bad_alloc : public exception {
  public:
    bad_alloc() throw()noexcept;
    bad_alloc(const bad_alloc&) throw()noexcept;
    bad_alloc& operator=(const bad_alloc&) throw()noexcept;
    virtual const char* what() const throw()noexcept;
  };
}

After p.1

bad_alloc() throw()noexcept;

After p.3


bad_alloc(const bad_alloc&) throw()noexcept;
bad_alloc& operator=(const bad_alloc&) throw()noexcept;

After p.4

virtual const char* what() const throw()noexcept;

18.6.2.2 Class bad_array_new_length


namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    bad_array_new_length() throw()noexcept;
  };
}

After p.1

bad_array_new_length() throw()noexcept;

18.6.2.4 set_new_handler

Before p.1

new_handler set_new_handler(new_handler new_p) throw()noexcept;

18.7.1 Class type_info


namespace std {
  class type_info {
  public:
    virtual ~type_info();
    bool operator==(const type_info& rhs) const;
    bool operator!=(const type_info& rhs) const;
    bool before(const type_info& rhs) const;
    size_t hash_code() const throw()noexcept;
    const char* name() const;
    type_info(const type_info& rhs) = delete; / cannot be copied
    type_info& operator=(const type_info& rhs) = delete; // cannot be copied
  };
}

After p.6

size_t hash_code() const throw()noexcept;

18.7.2 Class bad_cast


namespace std {
  class bad_cast : public exception {
  public:
    bad_cast() throw()noexcept;
    bad_cast(const bad_cast&) throw()noexcept;
    bad_cast& operator=(const bad_cast&) throw()noexcept;
    virtual const char* what() const throw()noexcept;
  };
}

After p.1

bad_cast() throw()noexcept;

After p.3


bad_cast(const bad_cast&) throw()noexcept;
bad_cast& operator=(const bad_cast&) throw()noexcept;

After p.4

virtual const char* what() const throw()noexcept;

18.7.3 Class bad_typeid


namespace std {
  class bad_typeid : public exception {
  public:
    bad_typeid() throw()noexcept;
    bad_typeid(const bad_typeid&) throw()noexcept;
    bad_typeid& operator=(const bad_typeid&) throw()noexcept;
    virtual const char* what() const throw()noexcept;
  };
}

After p.1

bad_typeid() throw()noexcept;

After p.3


bad_typeid(const bad_typeid&) throw()noexcept;
bad_typeid& operator=(const bad_typeid&) throw()noexcept;

After p.4

virtual const char* what() const throw()noexcept;

18.8 Exception handling

1 The header defines several types and functions related to the handling of exceptions in a C++ program.

Header <exception> synopsis


namespace std {
  class exception;
  class bad_exception;
  class nested_exception;

  typedef void (*unexpected_handler)();
  unexpected_handler set_unexpected(unexpected_handler f) throw()noexcept;
  [[noreturn]] void unexpected();

  typedef void (*terminate_handler)();
  terminate_handler set_terminate(terminate_handler f) throw()noexcept;
  [[noreturn]] void terminate();

  bool uncaught_exception() throw()noexcept;

  typedef unspecified exception_ptr;

  exception_ptr current_exception();
  [[noreturn]] void rethrow_exception(exception_ptr p);
  template<class E> exception_ptr make_exception_ptr(E e);

  [[noreturn]] template <class T> void throw_with_nested(T&& t);
  template <class E> void rethrow_if_nested(const E& e);
}

18.8.1 Class exception


namespace std {
  class exception {
  public:
    exception() throw()noexcept;
    exception(const exception&) throw()noexcept;
    exception& operator=(const exception&) throw()noexcept;
    virtual ~exception() throw()noexcept;
    virtual const char* what() const throw()noexcept;
  };
}

After p.2

exception() throw()noexcept;

After p.4


exception(const exception& rhs) throw()noexcept;
exception& operator=(const exception& rhs) throw()noexcept;

After p.6

virtual ~exception() throw()noexcept;

After p.8

virtual const char* what() const throw()noexcept;

18.8.2.1 Class bad_exception


namespace std {
  class bad_exception : public exception {
  public:
    bad_exception() throw()noexcept;
    bad_exception(const bad_exception&) throw()noexcept;
    bad_exception& operator=(const bad_exception&) throw()noexcept;
    virtual const char* what() const throw()noexcept;
  };
}

After p.1

bad_exception() throw()noexcept;

After p.3


bad_exception(const bad_exception&) throw()noexcept;
bad_exception& operator=(const bad_exception&) throw()noexcept;

After p.4

virtual const char* what() const throw()noexcept;

18.8.4.2 set_terminate

Before p.1

terminate_handler set_terminate(terminate_handler f) throw()noexcept;

18.8.5 uncaught_exception

Before p.1

bool uncaught_exception() throw()noexcept;

18.8.7 nested_exception


namespace std {
  class nested_exception {
  public:
    nested_exception() throw()noexcept;
    nested_exception(const nested_exception&) throw() = default;
    nested_exception& operator=(const nested_exception&) throw() = default;
    virtual ~nested_exception() = default;
  
    // access functions
    [[noreturn]] void rethrow_nested() const;
    exception_ptr nested_ptr() const;
  };

  [[noreturn]] template <class T> void throw_with_nested(T&& t);
  template <class E> void rethrow_if_nested(const E& e);
}

After p.2

nested_exception() throw()noexcept;

19.5.6.1 Class system_error overview

After p.2


namespace std {
  class system_error : public runtime_error {
  public:
    system_error(error_code ec, const string& what_arg);
    system_error(error_code ec, const char* what_arg);
    system_error(error_code ec);
    system_error(int ev, const error_category& ecat, const string& what_arg);
    system_error(int ev, const error_category& ecat, const char* what_arg);
    system_error(int ev, const error_category& ecat);
    const error_code& code() const throw()noexcept;
    const char* what() const throw()noexcept;
  };
} // namespace std

After p.12

const error_code& code() const throw()noexcept;

After p.13

const char *what() const throw()noexcept;

20.9 Memory

Header <memory> synopsis


namespace std {
  // 20.9.1, allocator argument tag
  struct allocator_arg_t { };
  constexpr allocator_arg_t allocator_arg = allocator_arg_t();

  // 20.9.2, uses_allocator
  template <class T, class Alloc> struct uses_allocator;

  // 20.9.3, pointer traits
  template <class Ptr> struct pointer_traits;
  template <class T> struct pointer_traits<T*>;

  // 20.9.4, allocator traits
  template <class Alloc> struct allocator_traits;

  // 20.9.5, the default allocator:
  template <class T> class allocator;
  template <> class allocator<void>;
  template <class T, class U>
    bool operator==(const allocator<T>&, const allocator<U>&) throw()noexcept;
  template lt;class T, class U>
    bool operator!=(const allocator<T>&, const allocator<U>&) throw()noexcept;

  ... Rest of synopsis
}

20.9.5 The default allocator


namespace std {
  template <class T> class allocator;

  // specialize for void:
  template <> class allocator<void> {
  public:
    typedef void* pointer;
    typedef const void* const_pointer;
    // reference-to-void members are impossible.
    typedef void value_type;
    template <class U> struct rebind { typedef allocator<U> other; };
  };

  template <class T> class allocator {
  public:
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;
    template <class U> struct rebind { typedef allocator<U> other; };

    allocator() throw()noexcept;
    allocator(const allocator&) throw()noexcept;
    template <class U> allocator(const allocator<U>&) throw()noexcept;
    ~allocator() throw()noexcept;

    pointer address(reference x) const;
    const_pointer address(const_reference x) const;

    pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
    void deallocate(pointer p, size_type n);
    size_type max_size() const throw()noexcept;

    template<class U, class... Args>
      void construct(U* p, Args&&... args);
    template <class U>
      void destroy(U* p);
  };
}

After p.10

size_type max_size() const throw()noexcept;

20.9.5.2 allocator globals

Before p.1


template <class T1, class T2>
bool operator==(const allocator<T1>&, const allocator<T2>&) throw()noexcept;

After p.1


template <class T1, class T2>
bool operator!=(const allocator<T1>&, const allocator<T2>&) throw()noexcept;

22.2 Header <locale> synopsis


namespace std {
  // 22.3.1, locale:
  class locale;
  template <class Facet> const Facet& use_facet(const locale&);
  template <class Facet> bool has_facet(const locale&) throw()noexcept;

  ... Rest of synopsis
}

22.3.1 Class locale


namespace std {
  class locale {
  public:
    // types:
    class facet;
    class id;
    typedef int category;
    static const category // values assigned here are for exposition only
      none = 0,
      collate = 0x010, ctype = 0x020,
      monetary = 0x040, numeric = 0x080,
      time = 0x100, messages = 0x200,
      all = collate | ctype | monetary | numeric | time | messages;

    // construct/copy/destroy:
    locale() throw()noexcept;
    locale(const locale& other) throw()noexcept;
    explicit locale(const char* std_name);
    explicit locale(const string& std_name);
    locale(const locale& other, const char* std_name, category);
    locale(const locale& other, const string& std_name, category);
    template <class Facet> locale(const locale& other, Facet* f);
    locale(const locale& other, const locale& one, category);
    ~locale() throw()noexcept; // not virtual
    const locale& operator=(const locale& other) throw()noexcept;
    template <class Facet> locale combine(const locale& other) const;

    // locale operations:
    basic_string<char> name() const;

    bool operator==(const locale& other) const;
    bool operator!=(const locale& other) const;

    template <class charT, class Traits, class Allocator>
      bool operator()(const basic_string<charT,Traits,Allocator>& s1,
                      const basic_string<charT,Traits,Allocator>& s2) const;

    // global locale objects:
    static locale global(const locale&);
    static const locale& classic();
  };
}

22.3.1.2 locale constructors and destructor

Before p.1

locale() throw()noexcept;

After p.2

locale(const locale& other) throw()noexcept;

After p.3

const locale& operator=(const locale& other) throw()noexcept;

After p.17

~locale() throw();

22.3.2 locale globals

After p.4

template  bool has_facet(const locale& loc) throw()noexcept;

22.4.1.3 ctype specializations


namespace std {
  template <> class ctype<char>
    : public locale::facet, public ctype_base {
  public:
    typedef char char_type;

    ...

    const mask* table() const throw()noexcept;
    static const mask* classic_table() throw()noexcept;

    ...
  };
}

22.4.1.3.2 ctype<char> members

After p.11

const mask* table() const throw()noexcept;

22.4.1.3.3 ctype<char> static members

Before p.1

static const mask* classic_table() throw()noexcept;

22.4.1.4 Class template codecvt


namespace std {
  class codecvt_base {
  public:
    enum result { ok, partial, error, noconv };
  };

  template <class internT, class externT, class stateT>
    class codecvt : public locale::facet, public codecvt_base {
  public:
    typedef internT intern_type;
    typedef externT extern_type;
    typedef stateT state_type;

    explicit codecvt(size_t refs = 0);

    result out(stateT& state, 
               const internT* from, const internT* from_end, const internT*& from_next, 
               externT* to, externT* to_end, externT*& to_next) const;
    result unshift(stateT& state,
                   externT* to, externT* to_end, externT*& to_next) const;
    result in(stateT& state,
              const externT* from, const externT* from_end, const externT*& from_next,
              internT* to, internT* to_end, internT*& to_next) const;
    int encoding() const throw()noexcept;
    bool always_noconv() const throw()noexcept;
    int length(stateT&, const externT* from, const externT* end,
               size_t max) const;
    int max_length() const throw()noexcept;

    static locale::id id;

  protected:
    ~codecvt();
    virtual result do_out(stateT& state,
                          const internT* from, const internT* from_end, const internT*& from_next,
                          externT* to, externT* to_end, externT*& to_next) const;
    virtual result do_in(stateT& state,
                         const externT* from, const externT* from_end, const externT*& from_next,
                         internT* to, internT* to_end, internT*& to_next) const;
    virtual result do_unshift(stateT& state,
                              externT* to, externT* to_end, externT*& to_next) const;
    virtual int do_encoding() const throw()noexcept;
    virtual bool do_always_noconv() const throw()noexcept;
    virtual int do_length(stateT&, const externT* from,
                          const externT* end, size_t max) const;
    virtual int do_max_length() const throw()noexcept;
  };
}

22.4.1.4.1 codecvt members

After p.3

int encoding() const throw()noexcept;

After p.4

bool always_noconv() const throw()noexcept;

After p.6

int max_length() const throw()noexcept;

22.4.1.4.2 codecvt virtual functions

After p.8

int do_encoding() const throw()noexcept;

After p.9

bool do_always_noconv() const throw()noexcept;

After p.13

int do_max_length() const throw()noexcept;

24.6.3 Class template istreambuf_iterator

2. The result of operator*() on an end-of-stream iterator is undefined. For any other iterator value a char_- type value is returned. It is impossible to assign a character via an input iterator.


namespace std {
  template<class charT, class traits = char_traits<charT> >
  class istreambuf_iterator
    : public iterator<input_iterator_tag, charT,
                         typename traits::off_type, unspecified , charT> {
  public:
    typedef charT char_type;
    typedef traits traits_type;
    typedef typename traits::int_type int_type;
    typedef basic_streambuf<charT,traits> streambuf_type;
    typedef basic_istream<charT,traits> istream_type;

    class proxy; // exposition only

    constexpr istreambuf_iterator() throw()noexcept;
    istreambuf_iterator(const istreambuf_iterator&) throw() = default;
    ~istreambuf_iterator() throw() = default;
    istreambuf_iterator(istream_type& s) throw()noexcept;
    istreambuf_iterator(streambuf_type* s) throw()noexcept;
    istreambuf_iterator(const proxy& p) throw()noexcept;
    charT operator*() const;
    pointer operator->() const;
    istreambuf_iterator<charT,traits>& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;
  private:
    streambuf_type* sbuf_; // exposition only
  };

  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT,traits>& a,
                    const istreambuf_iterator<charT,traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT,traits>& a,
                    const istreambuf_iterator<charT,traits>& b);
}

24.6.3.2 istreambuf_iterator constructors

Before p.1

constexpr istreambuf_iterator() throw()noexcept;

After p.1


istreambuf_iterator(basic_istream& s) throw()noexcept;
istreambuf_iterator(basic_streambuf* s) throw()noexcept;

After p.2

istreambuf_iterator(const proxy& p) throw()noexcept;

24.6.4 Class template ostreambuf_iterator


namespace std {
  template <class charT, class traits = char_traits<charT> >
  class ostreambuf_iterator :
    public iterator<output_iterator_tag, void, void, void, void> {
  public:
    typedef charT char_type;
    typedef traits traits_type;
    typedef basic_streambuf<charT,traits> streambuf_type;
    typedef basic_ostream<charT,traits> ostream_type;
  public:
    ostreambuf_iterator(ostream_type& s) throw()noexcept;
    ostreambuf_iterator(streambuf_type* s) throw()noexcept;
    ostreambuf_iterator& operator=(charT c);
    ostreambuf_iterator& operator*();
    ostreambuf_iterator& operator++();
    ostreambuf_iterator& operator++(int);
    bool failed() const throw()noexcept;
  private:
    streambuf_type* sbuf_; // exposition only
  };
}

24.6.4.1 ostreambuf_iterator constructors

Before p.1

ostreambuf_iterator(ostream_type& s) throw()noexcept;

After p.2

ostreambuf_iterator(streambuf_type* s) throw()noexcept;

24.6.4.2 ostreambuf_iterator operations

After p.4

bool failed() const throw()noexcept;

30.6.3 Class future_error


namespace std {
  class future_error : public logic_error {
    public:
      future_error(error_code ec); // exposition only
      const error_code& code() const throw()noexcept;
      const char* what() const throw()noexcept;
  };
}

Before p.1

const error_code& code() const throw()noexcept;

After p.1

const char *what() const throw()noexcept;