Использование std::setw() без заголовка

#c #fstream #clang #setw

Вопрос:

Как возможно, чтобы этот код компилировался, даже если я его не включал <iomanip> ?

 #include <iostream>
#include <fstream>

int main()
{
    std::cout << std::setw(5) << "test" << std::endl;
    return 0;
}
 

Компилируется с:

 clang   test.cpp
 

Но без <fstream> этого выдает ошибку:

 test.cpp:5:20: error: no member named 'setw' in namespace 'std'
        std::cout << std::setw(5) << "test" << std::endl;
                     ~~~~~^
1 error generated.
 

На Mac моих друзей это приводит к ошибке в обеих ситуациях.

Комментарии:

1. В вашей системе iomanip включен в заголовок fstream, поэтому он работает, но это определенная реализация, поэтому другой компилятор(-версия) в другой системе может определить fstream без iomanip.

2. Один или оба iostream и/или fstream могут сами рекурсивно включать несколько файлов заголовков и так далее. Вы можете использовать -H опцию clang (или g ), чтобы точно узнать iomanip , откуда включается.

Ответ №1:

Заголовки включают себя внутренне, в зависимости от реализации стандартной библиотеки.

Стандарт не гарантирует, что символ не определен, если вы не включите определенный файл — вместо этого он гарантирует, что символ будет определен, если вы его включите.

В этом случае fstream заголовок содержит внутренний код, который также имеет определение std::setw .

Код, компилируемый на вашем компиляторе, является особенностью реализации вашей стандартной библиотеки.

В нашем текущем проекте отсутствующие заголовки являются одной из распространенных причин неудачных сборок (сборка работает в Windows, но не на Mac, или наоборот).

Как правило, включайте указанные заголовки для всего, что вам требуется в вашем коде, даже если код компилируется нормально без включения.

Ответ №2:

Стандартные заголовки C могут включать другие стандартные заголовки, если это удобно для реализации. Ваш <fstream> в качестве детали реализации включен <iomanip> , но на Mac он, по-видимому, не был включен.

Правило: Включайте то, что вам нужно, и не полагайтесь на случайное включение. Это не накладывает накладных расходов; все стандартные заголовки могут быть безопасно включены более одного раза.