2016-07-17 7 views
4

Я делал конкурс онлайн-кодирования, и моя идея состояла в том, чтобы найти заголовок, который имеет более короткое имя, чем <iostream>, но включает в себя <iostream>. Ну, я до сих пор не преуспевал, но это заставило меня задаться вопросом:Указывает ли стандарт, какие заголовки включают другие заголовки?

Указывает ли стандарт, какие заголовки включают другие заголовки?

К примеру, на <iostream>cplusplus состояния:

В том числе этот заголовок может автоматически включать в себя другие заголовки, такие как <ios>, <streambuf>, <istream>, <ostream> и/или <iosfwd>.

Однако, когда я смотрю на <ios> нет такого заявления, как «Этот заголовок может быть включен <iostream>». Для некоторых заголовков я мог представить, что им нужно включить других для правильной работы. И если это так, я бы ожидал, что стандарт сделает некоторое утверждение о том, как заголовки зависят друг от друга (например, циклические зависимости следует избегать). Или стандарт просто удостоверяет, что таких зависимостей не существует, и это зависит от реализации?

+2

Не обращайтесь к 'cplusplus' за хорошую или рецензируемую информацию. – PaulMcKenzie

+0

@PaulMcKenzie, что является лучшим источником? Я не спросил в вопросе, потому что это было бы не в тему ... – user463035818

+2

Для одного, [этот сайт] (http://en.cppreference.com/w/). – PaulMcKenzie

ответ

2

От I знаю, что стандарт не указывает, какие заголовки включают другие заголовки - это реализация, а не то, на что вы должны положиться. Включите то, что вы используете.

Кроме того, вы можете предпочесть http://cppreference.com/ над http://cplusplus.com/ как есть (IMHO) гораздо более высокого качества.

+0

на cppref он говорит «inlcudes» вместо «can include», не означает ли это, что все реализации должны включать перечисленные заголовки? – user463035818

+0

@ tobi303 вправо, но * I * не может найти ничего, требуя такого «foo», включая «bar», гарантии в стандартном тексте. Если вы можете, то, пожалуйста, поделитесь информацией. –

1

В общем, нет, стандарт не указывает, что заголовки должны включать другие заголовки; это зависит от реализации, чтобы управлять получением имен из других заголовков, когда они необходимы, а стандартным заголовкам разрешено включать любые другие стандартные заголовки.

Единственным исключением является заголовок <initializer_list>; для включения этого заголовка требуются заголовки, в которых используются списки инициализаторов (например, контейнеры).

2

Общее правило о том, какие заголовки могут быть включены другими заголовками: есть несколько заголовков, которые указаны для включения автоматически, и, кроме этого, это зависит от реализации и не требует документирования.

17.6.5.1 Соответствующие реализации [соответствующие]

17.6.5.2 Заголовки [res.on.headers]

1 заголовка C++ может включать в себя другие заголовки C++. Заголовок C++ должен содержать декларации и определения, которые содержатся в его кратком описании. Заголовок C++, показанный в его кратком обзоре, как включающий другие заголовки C++, должен содержать описания и определения, которые появляются в синонимах этих других заголовков.

Это правило о "показано в конспект как включая другие заголовки C++" относится к:

  • <utility>, <string>, <array>, <deque>, <forward_list>, <list>, <vector>, <map>, <set>, <unordered_map>, <unordered_set> , <queue>, <stack>, <algorithm>, <random>, <valarray>, <regex> включая <initializer_list>.
  • <bitset> содержит <string>, <iosfwd>.
  • <iostream> содержит <ios>, <streambuf>,, <ostream>.
  • <ios> содержит <iosfwd>.

Однако, хотя, например, <ios> показан как включающий в себя <iosfwd>, реализация может быть в состоянии достичь требований без фактического включения в нее и для [res.on.headers], что очень хорошо. По большей части не имеет значения, включает ли реализация другие заголовки, если объявленные функции и типы становятся доступными.

1

Это зависит от , какая версия стандарта имеет отношение к. C++ 98 и C++ 03 не требуют никаких требований к заголовкам, включая другие заголовки.

Начиная с C++ 11 или C++ 14, стандарт делает мандат, который содержит некоторые заголовки других заголовков.

Все версии стандарта потребовали, чтобы один и тот же заголовок несколько раз был безопасным.

Итак, если вы знаете, что вам нужен конкретный заголовок, и вы работаете над компилятором, который реализует старый стандарт, просто #include заголовок.