Are C++ standard library implementations allowed to add public (and protected) members to standard types' interfaces? N3797 17.6.5.5 [member.functions]/2 says:
An implementation may declare additional non-virtual member function signatures within a class:
— by adding arguments with default values to a member function signature; [ Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note ]
— by replacing a member function signature with default values by two or more member function signatures with equivalent behavior; and
— by adding a member function signature for a member function name.
Does this mean that a standard library cannot add any additional public members with names not mentioned in the standard under any circumstances (that include, for example, reserved identifiers)?
A tiny bit of explanation: this is the text about adding signatures (which I assume talks about new signatures just for functions that are already defined to be there, so no new names) I managed to find in the standard. There is also the footnote 189, which says:
A valid C++ program always calls the expected library member function, or one with equivalent behavior. An implementation may also define additional member functions that would otherwise not be called by a valid C++ program.
All this text originates from [member.functions], so it is clearly about member functions only. My question is more generic and asks for any references I could've missed: is a standard library implementation allowed to add new names to public (and/or protected) interfaces of a standard type, be it data or function members?
All interface methods are public by default (even if you don't specify it explicitly in the interface definition), so all implementing methods must be public too, since you can't reduce the visibility of the interface method.
Interfaces can now have the default implementation of methods. Interfaces can now have Private members. Interfaces can now also have static members. This is used for parameterization of the default implementation.
With C# 8.0, you can now have default implementations of methods in an interface. Interface members can be private, protected, and static as well. Protected members of an interface cannot be accessed in the class that extends the interface.
Interfaces can have default methods with implementation in Java 8 on later. Interfaces can have static methods as well, similar to static methods in classes. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.
I believe you have what you need with a combination of foot note 189
which says:
A valid C++ program always calls the expected library member function, or one with equivalent behavior. An implementation may also define additional member functions that would otherwise not be called by a valid C++ program.
and section 17.6.5.11
Derived classes which says:
An implementation may derive any class in the C++ standard library from a class with a name reserved to the implementation.
but does not add any restrictions, i.e. it does not let's say restrict the access qualifiers etc...
and we can see libstdc++ uses derived classes pretty effectively, for example in stl_vector.h. Although as far as I can see libstdc++
does seem to eschew adding public data members but that is probably more for clean design.
At minimum, this looks under-specified but if you stick to something similar to libstdc++
implementation style you should be good.
I think that the key to reading footnote 189 is the phrase would otherwise not be called by a valid C++ program
.
Remember that identifiers beginning with an underscore followed by a capital letter (or containing two consecutive underscores anywhere) are reserved for the implementation. (section 17.6.4.3.2)
So implementations are free to add public/protected member functions that are named in that manner.
For example, in libc++, std::vector
has a protected member function named __throw_length_error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With