Подтвердить что ты не робот

Разрешено ли реализациям добавлять публичных членов к стандартным типам?

Разрешены ли стандартные реализации библиотек С++ для добавления общедоступных (и защищенных) элементов к интерфейсам стандартных типов? N3797 17.6.5.5 [member.functions]/2 говорит:

Реализация может объявлять дополнительные не-виртуальные сигнатуры функций-членов внутри класса:

- путем добавления аргументов с значениями по умолчанию в подпись функции-члена; [Примечание. Реализация может не добавлять аргументы со значениями по умолчанию для виртуальных, глобальных или не-членов. - конечная нота]

- путем замены сигнатуры функции-члена стандартными значениями на две или более подписи функций-членов с эквивалентным поведением; и

- путем добавления сигнатуры функции-члена для имени функции-члена.

Означает ли это, что стандартная библиотека не может добавлять каких-либо дополнительных публичных пользователей с именами, не упоминаемыми в стандарте ни при каких обстоятельствах (включая, например, зарезервированные идентификаторы)?

Небольшое объяснение: это текст о добавлении подписей (который, я предполагаю, говорит о новых подписях только для функций, которые уже определены там, поэтому нет новых имен), которые мне удалось найти в стандарте. Существует также сноска 189, в которой говорится:

Действительная программа на С++ всегда вызывает функцию ожидаемого библиотечного элемента или одну с эквивалентным поведением. Реализация также может определять дополнительные функции-члены, которые иначе не могли бы вызываться действительной программой на С++.

Весь этот текст исходит из [member.functions], поэтому он явно касается только функций-членов. Мой вопрос более общий и запрашивает любые ссылки, которые я мог пропустить: стандартная реализация библиотеки позволяет добавлять новые имена в общедоступные (и/или защищенные) интерфейсы стандартного типа, будь то данные или члены функции?

4b9b3361

Ответ 1

Я считаю, что у вас есть то, что вам нужно, с сочетанием нотной записки 189, которая гласит:

Действительная программа на С++ всегда вызывает функцию ожидаемого библиотечного элемента или одну с эквивалентным поведением. Реализация также может определять дополнительные функции-члены, которые иначе не могли бы вызываться действительной программой на С++.

и раздел 17.6.5.11 Производные классы, которые гласят:

Реализация может выводить любой класс в стандартной библиотеке С++ из класса с именем, зарезервированным для реализации.

но не добавляет никаких ограничений, т.е. не позволяет ограничивать квалификаторы доступа и т.д.

и мы можем видеть libstdc++ эффективно использует производные классы, например, в stl_vector.h. Хотя, насколько я вижу, libstdc++, похоже, избегает добавления публичных элементов данных, но это, вероятно, больше для чистого дизайна.

Как минимум, это выглядит недооцененным, но если вы придерживаетесь чего-то похожего на стиль реализации libstdc++, вы должны быть хорошими.

Ответ 2

Я думаю, что ключом к чтению сноски 189 является фраза would otherwise not be called by a valid C++ program.

Помните, что для реализации зарезервированы идентификаторы, начинающиеся с символа подчеркивания, за которым следует большая буква (или содержащая два подряд подряд символа подчеркивания). (раздел 17.6.4.3.2)

Таким образом, реализации могут свободно добавлять публичные/защищенные функции-члены, которые названы таким образом.

Например, в libС++ std::vector имеет защищенную функцию-член с именем __throw_length_error