The current idiom is to declare the copy operations as private, and choose not to implement them as they are never called. While this technique works, it is far from obvious - especially when trying to explain to someone new to the language why they would want to declare a function they never plan to define. While this new specifier still requires declaring the functions, at least it is clear that it is not permitted to define them, and the compiler will enforce this for you. It is much simpler to teach to the casual programmer, who is wondering how they are supposed to know which private functions have definitions, and which are just for show. This is further strengthened when the casual programmer comes back and points out that the class itself (by current convention) can still make copies, and likewise any friends. These errors go straight past the translator and are only caught at link time, which is not the easiest time for causal programmers to be diagnosing errors. Again, the use of prohibited as an access specifier takes these questions away, and the code clearly states its intent. Example 2 : Prevent Narrowing conversionstemplate< typename T > struct owned_ptr { public: explicit owned_ptr( T * p ) : pt( p ) {} ~owned_ptr() { delete pt; } T * operator->() { return pt; } T const * operator->() const { return pt; } private: T * pt; prohibited: owned_ptr( owned_ptr const & ); owned_ptr & operator=( owned_ptr const & ); };
Again, the prohibited access specifier more clearly expresses the intent than an unimplemented private function. This example seems more likely to benefit from the diagnostics when calling the double overload from other members of friends.struct X { public: void foo( float ); prohibited: void foo( double ); };
Clause 10:Notes:
Augment the grammar for access-specifier with prohibited Add to Clause 11 p 1: [class.access] prohibited: that is, the name cannot be used. [Note: a program is ill-formed if it tries to provide a definition for a prohibited member] Add paragraph 6 to clause 11.1 [class.access.spec] The member-specification for a prohibited access-specifier may only contain non-static, non-virtual function declarations, or shall be empty. Append to 11.2p1 [class.access.base] A program is ill-formed if a class is declared to be a base class for another class using the prohibited access specifier.
Nothing to say about friends (11.4), existing wording already covers the case.
Nothing to say about using declarations (7.3.3) - they are ill-formed by 11p1.
Nothing to say about access declarations (11.3) as they are defined in terms of using declarations.