Когда вы можете опустить расширение файла в директиве #include?

Я играю с gmock и замечаю, что он содержит эту строку:

#include <tuple>

Я бы ожидал tuple.h.

Когда можно исключить расширение, и дает ли это директиве другое значение?

Ответ 1

Стандартные заголовки 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) по нескольким причинам:

  1. если & когда библиотека станет стандартизированной, стандартная версия не будет автоматически переопределять предыдущую, нестандартную (по всей вероятности, из-за неправильного пользовательского кода)
  2. Кажется, существует соглашение (более или менее), что заголовки без суффикса являются стандартными библиотеками, а заголовки без суффикса (кроме старых заголовков C) нестандартны.

Обратите внимание, что аналогичная проблема возникла, когда комитет пошел добавлять хеш-карты в STL - они обнаружили, что уже существует много (разных) реализаций hash_map, поэтому вместо того, чтобы придумать стандартную, которая ломает много вещей там. сегодня они называют стандартную реализацию " unordered_map ". Предполагалось, что пространства имен помогут предотвратить этот тип прыжков через обручи, но, похоже, он не работает достаточно хорошо (или не используется достаточно), чтобы позволить им использовать более естественное имя, не нарушая много кода.

Обратите внимание, что для заголовков "C" C++ позволяет вам включить вариант <cxxxxxx> или <xxxxxx.h>. Тот, который начинается с 'c' и не имеет суффикса ".h", помещает свои объявления в пространство имен std (и, возможно, глобальное пространство имен), а те, которые имеют суффикс ".h", помещают имена в глобальное пространство имен (некоторые компиляторы). также поместите имена в пространство имен std - мне неясно, соответствует ли этот стандарт, хотя я не вижу вреда).

Ответ 2

Если файл имеет имя tuple, вам нужно #include <tuple> если он назван tuple.h, тогда вам нужно #include <tuple.h>

Это так просто. Вы не пропускаете расширение.

Ответ 3

Он включает файл, который просто называется "tuple" - сам файл не имеет расширения.

Предполагаемый стандарт для файлов С++ include - это их имя без расширения .h; многие авторы библиотек следуют этому стандарту (STL и т.д.), но некоторые из них этого не делают.

Ответ 4

Нет ничего особенного. Файл просто называется tuple.

Причина этого... что стандартные заголовки библиотек не имеют расширения файла из-за namespace s.

Пространства имен были добавлены к стандарту С++ в конце игры со стандартом С++ 98, включая пространство имен std, в котором находятся все объекты стандартной библиотеки.

Когда стандартная библиотека переместилась в пространство имен std, это означало, что весь существующий код на С++ сломается, поскольку все это ожидало, что библиотека будет в глобальном пространстве имен. Решение заключалось в том, чтобы оставить старые файлы заголовков "dot-h" в отдельности и предоставить библиотеку с именами в файлах, которые не имеют расширения.

Таким образом, старый код, который #include<iosteam.h> мог бы ожидать глобального cout, в то время как новый код мог бы #include<iostream> и ожидать a std::cout.

Ответ 5

Я понял, что #include tuple будет "указывать" на tuple.h.

Проверьте это: iostream vs iostream.h

Ответ 6

В дополнение к уже опубликованным тонким ответам следует отметить, что для стандарта С++ не требуется директива "#include <iostream>" для чтения файла с именем "iostream" или даже "iostream.h". Его можно назвать "fuzzball". Или, никакой соответствующий файл не может существовать, и определения должны быть встроены в компилятор и активированы директивой include.

Ответ 7

Люди,

Я думаю, что сделка: #include <lib> allways pre pends/lib/include к пути поиска (.h - infrerred), тогда как #include < lib.h > ищет только -I <pathname> .

Обратите внимание, что я могу ошибаться... Я просто думаю, что это работает (в Forte cc на Solaris).