Разрешено ли реализациям стандартной библиотеки C ++ добавлять открытые (и защищенные) члены к интерфейсам стандартных типов? N3797 17.6.5.5 [member.functions] / 2 говорит:
Реализация может объявить дополнительные не виртуальные сигнатуры функций-членов в классе:
— путем добавления аргументов со значениями по умолчанию к сигнатуре функции-члена; [ ЗаметкаРеализация не может добавлять аргументы со значениями по умолчанию к виртуальным, глобальным функциям или функциям, не являющимся членами. — конечная нота ]
— путем замены сигнатуры функции-члена значениями по умолчанию двумя или более сигнатурами функции-члена с эквивалентным поведением; а также
— путем добавления сигнатуры функции-члена для имени функции-члена.
Означает ли это, что стандартная библиотека не может добавлять какие-либо дополнительные открытые члены с именами, не упомянутыми в стандарте, ни при каких обстоятельствах (например, зарезервированные идентификаторы)?
Небольшое объяснение: это текст о добавлении сигнатур (который, как я предполагаю, говорит о новых сигнатурах только для функций, которые уже определены, чтобы быть там, поэтому нет новых имена) Мне удалось найти в стандарте. Есть также сноска 189, которая гласит:
Действительная программа C ++ всегда вызывает ожидаемую библиотечную функцию-функцию или функцию с эквивалентным поведением. Реализация также может определять дополнительные функции-члены, которые в противном случае не были бы вызваны допустимой программой C ++.
Весь этот текст происходит от [member.functions], поэтому он явно касается только функций-членов. Мой вопрос носит более общий характер и требует каких-либо ссылок, которые я мог бы пропустить: стандартная реализация библиотеки позволяет добавлять новые имена к открытым (и / или защищенным) интерфейсам стандартного типа, будь то данные или функции-члены?
Я полагаю, что у вас есть то, что вам нужно с сочетанием примечания ноги 189
который говорит:
Действительная программа C ++ всегда вызывает ожидаемую библиотечную функцию-функцию или функцию с эквивалентным поведением. Реализация также может определять дополнительные функции-члены, которые в противном случае не были бы вызваны допустимой программой C ++.
и раздел 17.6.5.11
Производные классы который говорит:
Реализация может получить любой класс в стандартной библиотеке C ++ из класса с именем, зарезервированным для реализации.
но не добавляет никаких ограничений, то есть не допустит ограничения доступа и т. д.
и мы можем видеть libstdc ++ довольно эффективно использует производные классы, например, в stl_vector.h. Хотя насколько я могу видеть libstdc++
кажется, избегают добавления открытых элементов данных, но это, вероятно, больше для чистого дизайна.
Как минимум, это выглядит недостаточно определенным, но если вы придерживаетесь чего-то похожего на libstdc++
Стиль реализации у вас должен быть хорошим.
Я думаю, что ключом к чтению сноски 189 является фраза would otherwise not be called by a valid C++ program
,
Помните, что идентификаторы, начинающиеся со знака подчеркивания, за которым следует заглавная буква (или содержащая два последовательных знака подчеркивания в любом месте), зарезервированы для реализации. (раздел 17.6.4.3.2)
Таким образом, реализации могут свободно добавлять открытые / защищенные функции-члены, которые названы таким образом.
Например, в libc ++, std::vector
имеет защищенную функцию-член с именем __throw_length_error