Когда вы можете опустить расширение файла в директиве #include?
Я играю с gmock и заметил, что он содержит эту строку:
#include <tuple>
Я бы ожидал tuple.h
,
Когда можно исключить расширение, и придает ли оно директиву другое значение?
7 ответов
Стандартные заголовки C++ не имеют суффикса ".h". Я полагаю, что причина в том, что было много разных предстандартных реализаций, которые стандарт может нарушить. Поэтому вместо того, чтобы требовать, чтобы поставщики изменили свой существующий заголовок "iostream.h" (например), чтобы он соответствовал стандартам (что нарушило бы их существующий код пользователя), комитет по стандартам решил, что они удалили суффикс (который, я думаю, нет тогда существующая реализация уже была сделана).
Таким образом, существующие нестандартные программы будут продолжать работать с использованием нестандартных библиотек поставщика. Когда пользователь хочет сделать свои программы совместимыми со стандартами, одним из шагов, которые он должен сделать, является изменение "#include
директива для удаления суффикса ".h".
Так
#include <iostream> // include the standard library version
#include <iostream.h> // include a vendor specific version (which by
// now might well be the same)
Как уже упоминалось в других ответах, авторы нестандартных библиотек могут выбрать либо соглашение об именах, но я думаю, что они захотят продолжить использовать ".h" или ".hpp" (как это сделал Boost) по нескольким причинам:
- если & когда библиотека станет стандартизированной, стандартная версия не будет автоматически переопределять предыдущую, нестандартную (по всей вероятности, из-за неправильного пользовательского кода)
- Кажется, существует соглашение (более или менее), что заголовки без суффикса являются стандартными библиотеками, а заголовки без суффикса (кроме старых заголовков C) нестандартны.
Обратите внимание, что аналогичная проблема возникла, когда комитет пошел добавлять хэш-карты в STL - они обнаружили, что их уже много (разных). hash_map
реализации, которые существуют, поэтому вместо того, чтобы придумать стандартную, которая сегодня ломает много вещей, они называют стандартную реализацию "unordered_map
Msgstr "Пространства имен должны были помочь предотвратить этот тип прыжков через обручи, но, похоже, он не работал достаточно хорошо (или не использовался достаточно хорошо), чтобы позволить им использовать более естественное имя, не нарушая много кода.
Обратите внимание, что для заголовков "C" C++ позволяет вам включать <cxxxxxx>
или же <xxxxxx.h>
вариант. Тот, который начинается с 'c' и не имеет суффикса ".h", помещает свои объявления в std
пространство имен (и, возможно, глобальное пространство имен), те, которые имеют суффикс ".h", помещают имена в глобальное пространство имен (некоторые компиляторы также помещают имена в std
пространство имен - мне неясно, соответствует ли оно стандартам, хотя я не вижу вреда).
Если файл назван tuple
тогда вам нужно #include <tuple>
если это называется tuple.h
тогда вам нужно #include <tuple.h>
Это так просто. Вы не опускаете никаких расширений.
Он включает в себя файл, который просто называется "кортеж" - сам файл не имеет расширения.
Предполагаемый стандарт для включаемых файлов C++ - именовать их без расширения.h; многие авторы библиотек следуют этому стандарту (STL и т. д.), но некоторые - нет.
Ничего особенного не происходит. Файл просто назван tuple
,
Причина этого в том, что заголовки стандартной библиотеки не имеют расширения файла, namespace
s.
Пространства имен были добавлены в стандарт C++ в конце игры со стандартом C++98, включая std
пространство имен, в котором находятся все стандартные объекты библиотеки.
Когда стандартная библиотека была перемещена в std
namespace, это означало, что весь существующий код C++ сломался, так как все ожидали, что библиотека будет в глобальном пространстве имен. Решение состояло в том, чтобы оставить старые заголовочные файлы "dot-h" в покое и предоставить библиотеку пространства имен в файлах, которые не имеют расширения.
Таким образом, старый код, который будет #include<iosteam.h>
можно ожидать глобального cout
в то время как новый код мог #include<iostream>
и ожидать std::cout
,
В дополнение к уже опубликованным прекрасным ответам следует отметить, что стандарт C++ не требует директивы "#include <iostream>
"для чтения файла с именем" iostream "или даже" iostream.h ". Он может быть назван"fuzzball". Или не может быть никакого соответствующего файла, и определения могут быть встроены в компилятор и активированы директивой include.
Насколько я понимаю, кортеж #include будет "указывать" на tuple.h.
Проверьте это: iostream vs iostream.h
Folks,
Я думаю, что дело в следующем: #include
Пожалуйста, обратите внимание, что я могу ошибаться... Просто я думаю, что это работает (в Forte cc на Solaris).