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

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

#include <tuple>

Я ожидал tuple.h.

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
47
0
13 074
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

Насколько мне известно, файлы Boost имеют расширение .hpp.

mannicken 14.01.2009 04:29

Насколько я понимаю, кортеж #include будет «указывать» на tuple.h.

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

Компилятор может решить, что это так. Преобразование строки в исходном коде в полный путь к файлу для ОС зависит от компилятора. Использование префиксов каталогов довольно распространено, а расширения - нет.

MSalters 14.01.2009 13:20

Ссылка не работает

Incomprehensible monad 14.12.2018 18:58
Ответ принят как подходящий

Стандартные заголовки 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 - мне неясно, соответствует ли это стандарту, хотя я не вижу вреда).

другая (хотя, вероятно, не основная причина :)) может указывать на то, что стандартные заголовки не обязательно должны быть файлами. поэтому они могли бы отказаться от «.h», потому что он предполагает расширение файла.

Johannes Schaub - litb 14.01.2009 07:26

Так было с ANSI C 1989, в котором есть сноска: «Заголовок не обязательно является исходным файлом ...» Между прочим - знает ли кто-нибудь о компиляторе, который делает что-то отличное от обычных исходных файлов для стандартных заголовков?

Michael Burr 14.01.2009 08:42

@MichaelBurr Разве предварительно скомпилированные заголовки не подходят под этот счет?

Peter - Reinstate Monica 13.10.2015 17:04

Правильное использование пространств имен действительно разрешило бы любые потенциальные конфликты между пользовательским кодом и кодом стандартной библиотеки, к сожалению, многие потребители библиотеки STL имеют некоторую форму using namespace std; в их исходных файлах, и, к сожалению (поскольку в C++ обратная совместимость является королем), комитет решил, что это оправдывает использование другого названия.

Tyg13 27.03.2019 17:13

Ничего особенного не происходит. Имя файла просто tuple.

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

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

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

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

Просто нашел противоположное утверждение и хотел указать на него. Питер Беккер утверждает, что «Пространства имен не имеют ничего общего с именами заголовков».

Daniel K. 03.01.2021 13:16

@DanielK. Я считаю, что это заявление вырвано из контекста. Вы читали следующий комментарий Питера Беккера? Кажется, пересказываю объяснение в этом ответе.

Drew Dormann 03.01.2021 20:22

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

Близкие,

Я думаю, что сделка такова: #include <lib> всегда предварительноpends / lib / include в путь поиска (подразумевается .h), тогда как #include <lib.h> выполняет поиск только -I <pathname>.

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

Вы ошибаетесь - стандартный C++ не определяет пути поиска.

anon 23.05.2009 14:15

Трудно избежать -1, признав, что вы могли ошибаться ... а это так. :-)

R.. GitHub STOP HELPING ICE 09.07.2010 19:15

Другие вопросы по теме