c++c++11stdstandardsreverse-iterator

Exposition only in the C++ standard?


What does exposition only exactly mean in the C++ standard? Does it mean that the private/protected members marked exposition only are required to exist by standard, or are they just a "suggestion" of implementation, and are not required at all?

Examples include:

std::error_code::val_
std::wstring_convert::byte_err_string
std::array::elems
std::move_iterator::current
std::reverse_iterator::current
std::ostream_iterator::delim
// And a lot of others

Solution

  • Exposition-only members are used to simplify a behavioural specification. Once the exposition-only member has been introduced and given a name, the semantics of the class can be specified in terms of it, but it is understood that what's being specified are only the semantics of the class, and the member itself is not part of that. Any conforming implementation only has to behave the same way as described in the specification that refers to the member.

    For example, suppose I want to specify a pointer wrapper class that exposes the wrappee. I could say, "Class Foo holds a reference to an object of type T which is given its constructor, and Foo::get exposes that object." That's very verbose and imprecise. Alternatively, I could specify this with an exposition-only member:

    Class Foo holds a reference to an object of type T.

    class Foo {
      const T* ptr;   // exposition-only
    
    public:
      // Constructor                                 // ┐
      Foo(const T& t) : ptr(std::addressof(t)) {}    // │
                                                     // ├─ real specification
      // Accessor                                    // │
      const T& get() const { return *ptr; }          // ┘
    };
    

    The specification of the individual member functions becomes much easier when I'm allowed to refer to some particular implementation, but it is understood that you can implement this in any way you like (e.g. with base classes or private nested types), and that the member Foo::ptr is not part of the specification. But having it allows me to specify the sematnics of the member functions in code rather than in words.