FWIW, я ненавижу файлы .inl. Зачем разбивать код больше, чем необходимо?
Shog9,
10
@ shog9: Чтобы отделить интерфейс от реализации. Я всегда ненавидел C # и файлы Java, потому что интерфейс очень трудно читать из-за всех деталей реализации messey.
Мартин Йорк
8
@Martin - к сожалению, C ++ дает нам плохую комбинацию обоих миров - интерфейса и части реализации в заголовке, остальной реализации в файле .cpp. Даже если вы избегаете встроенных функций (или помещаете их в файлы .inl), вам придется загромождать интерфейс надоедливыми деталями частных членов, если только вы не можете религиозно использовать идиому pimpl.
Майкл Берр,
5
Да, я никогда не понимал, что заголовки отделяют интерфейс от реализации. Очевидно, они этого не делают. Интерфейс не должен содержать всех закрытых членов.
jalf
@LokiAstari: Честно говоря, Java / C # имеет очень хороший инструментарий, автоматически обеспечивающий структуру интерфейса. Можно было бы сказать иначе: в C ++ вы должны вручную решать проблему, которую полностью могут решить компьютеры.
bluenote10
Ответы:
140
.inlфайлы никогда не являются обязательными и не имеют особого значения для компилятора. Это просто способ структурирования вашего кода, который дает подсказку людям, которые могут его прочитать.
Я использую .inlфайлы в двух случаях:
Для определений встроенных функций.
Для определений шаблонов функций.
В обоих случаях я помещал объявления функций в заголовочном файле, который включен другими файлами, то я #includeна .inlфайл в нижней части заголовка файла.
Мне это нравится, потому что он отделяет интерфейс от реализации и упрощает чтение файла заголовка. Если вас интересуют детали реализации, вы можете открыть .inlфайл и прочитать его. Если нет, то не обязательно.
Действительно, в основном речь идет об отделении интерфейса от реализации.
Павел Минаев
1
Я также видел .ipp и .ixx, используемые для встроенных определений, и .tpp и .txx для первого шаблона.
AProgrammer
1
Например, Стандартная библиотека C ++ GNU использует .tccфайлы реализации шаблонов.
musiphil 03
2
@NickMeyer glmиспользует .hpp и .inl точно так же, как вы упомянули выше. Полезно знать, спасибо за отличный ответ :)
legends2k
Так это похоже на заголовок?
Аарон Франке,
90
Ник Мейер прав: компилятор не заботится о расширении файла, который вы включаете, поэтому такие вещи, как «.h», «.hpp», «.hxx», «.hh», «.inl», ".inc" и т. д. - это простое соглашение, поясняющее, что файлы должны содержать.
Лучшим примером являются файлы заголовков STL, у которых нет вообще никаких расширений.
Обычно файлы ".inl" содержат встроенный код (отсюда и расширение ".inl").
Эти файлы ".inl" необходимы, когда у вас есть цикл зависимости между кодом заголовка .
Например:
// A.hppstruct A
{void doSomethingElse(){// Etc.}void doSomething(B & b){
b.doSomethingElse();}};
И:
// B.hppstruct B
{void doSomethingElse(){// Etc.}void doSomething(A & a){
a.doSomethingElse();}};
Вы не сможете его скомпилировать, в том числе с использованием прямого объявления.
Решение состоит в том, чтобы разбить определение и реализацию на два типа файлов заголовков:
hpp для объявления / определения заголовка
inl для реализации заголовка
Что можно увидеть в следующем примере:
// A.hppstruct B ;struct A
{void doSomethingElse();void doSomething(B & b);};
Это объясняет реальную пользу (или необходимость) разделения, и это должно было быть выбрано в качестве ответа.
musiphil 03
1
Если бы функция не была встроенной, вы бы использовали стандартный файл .cpp для реализации?
Bublafus
1
@Bublafus If the function were not inline, you would you standard .cpp file for the implementation part?:: Возможно. Шаблоны - это примеры кода, который обычно нельзя скрыть в файлах .CPP, поэтому в этом случае файл .INL будет обязательным.
paercebal
32
Поскольку никто об этом не упомянул:
Использование файлов .inl для хранения встроенных функций может быть полезно для ускорения компиляции.
Если вы включаете только объявления (.h) там, где вам нужны объявления, и включаете только встроенные реализации (.inl) там, где они вам нужны (т.е., вероятно, только в .cpp и других файлах .inl, а не в .h), он может иметь благотворно влияет на зависимости ваших заголовков.
Это может быть значительной победой для более крупных проектов с большим количеством взаимодействующих классов.
+1: мир определенно становится другим, когда вы управляете миллионами строк кода и тысячами файлов.
gatorfax
Значит, вы никогда не должны включать .inl в файлы заголовков? У меня всегда было ощущение, что .inl следует помещать в конец заголовочных файлов, поскольку встроенные функции требуют, чтобы объявление и реализация были доступны сразу.
Icebone1000
1
Icebone1000 не все модули, которые включают заголовок, обязательно хотят использовать встроенные функции, поэтому им не нужно читать реализации, они не должны присутствовать, если они не используются.
Andy J Buchanan
1
Я не понимаю, как это может быть быстрее, поскольку компилятору нужно проделать больше работы, чтобы включить и объединить единицы перевода.
Никос
1
@Nikos Я думаю, он имел в виду быстрее по сравнению с помещением всех ваших встроенных функций в ваши файлы заголовков.
CoffeeTableEspresso
3
По моему опыту, файлы .inl используются для определения встроенных функций. Когда они находятся в файле .inl, файл может быть включен в заголовок для получения встроенных функций и в файл .c для получения обычных определений функций.
Таким образом, один и тот же источник может легче работать с компиляторами, которые не имеют встроенной поддержки функций, а также с компиляторами, которые имеют.
Обычно они используются с прямым кодом C, не часто с кодом C ++, поскольку все компиляторы C ++ поддерживают встроенные функции.
Я не вижу смысла делать это только для того, чтобы получить поддержку C. Для C вы просто условно #define inline staticопределите свои встроенные функции в заголовке.
Павел Минаев
Я думаю, это позволяет избежать попадания нескольких копий одной и той же функции в двоичный файл. Я просто говорю, что видел файлы .inl, используемые таким образом, но не то, чтобы это единственный метод (или даже лучший).
Майкл Берр,
1
Я считаю, что это просто соглашение об именах для файла «заголовка», включающего встроенный код. это так, что файлы .h могут содержать определения, а файлы .inl содержат встроенный код, необходимый для шаблонов.
Я не верю, что это что-то большее, чем соглашение об именах, чтобы прояснить цель файла
Ответы:
.inl
файлы никогда не являются обязательными и не имеют особого значения для компилятора. Это просто способ структурирования вашего кода, который дает подсказку людям, которые могут его прочитать.Я использую
.inl
файлы в двух случаях:В обоих случаях я помещал объявления функций в заголовочном файле, который включен другими файлами, то я
#include
на.inl
файл в нижней части заголовка файла.Мне это нравится, потому что он отделяет интерфейс от реализации и упрощает чтение файла заголовка. Если вас интересуют детали реализации, вы можете открыть
.inl
файл и прочитать его. Если нет, то не обязательно.источник
.tcc
файлы реализации шаблонов.glm
использует .hpp и .inl точно так же, как вы упомянули выше. Полезно знать, спасибо за отличный ответ :)Ник Мейер прав: компилятор не заботится о расширении файла, который вы включаете, поэтому такие вещи, как «.h», «.hpp», «.hxx», «.hh», «.inl», ".inc" и т. д. - это простое соглашение, поясняющее, что файлы должны содержать.
Лучшим примером являются файлы заголовков STL, у которых нет вообще никаких расширений.
Обычно файлы ".inl" содержат встроенный код (отсюда и расширение ".inl").
Эти файлы ".inl" необходимы, когда у вас есть цикл зависимости между кодом заголовка .
Например:
И:
Вы не сможете его скомпилировать, в том числе с использованием прямого объявления.
Решение состоит в том, чтобы разбить определение и реализацию на два типа файлов заголовков:
hpp
для объявления / определения заголовкаinl
для реализации заголовкаЧто можно увидеть в следующем примере:
И:
И:
И:
Таким образом, вы можете включить любой файл ".inl" в свой собственный источник, и он будет работать.
Опять же, суффиксные имена включаемых файлов не так важны, как их использование.
источник
If the function were not inline, you would you standard .cpp file for the implementation part?
:: Возможно. Шаблоны - это примеры кода, который обычно нельзя скрыть в файлах .CPP, поэтому в этом случае файл .INL будет обязательным.Поскольку никто об этом не упомянул:
Использование файлов .inl для хранения встроенных функций может быть полезно для ускорения компиляции.
Если вы включаете только объявления (.h) там, где вам нужны объявления, и включаете только встроенные реализации (.inl) там, где они вам нужны (т.е., вероятно, только в .cpp и других файлах .inl, а не в .h), он может иметь благотворно влияет на зависимости ваших заголовков.
Это может быть значительной победой для более крупных проектов с большим количеством взаимодействующих классов.
источник
По моему опыту, файлы .inl используются для определения встроенных функций. Когда они находятся в файле .inl, файл может быть включен в заголовок для получения встроенных функций и в файл .c для получения обычных определений функций.
Таким образом, один и тот же источник может легче работать с компиляторами, которые не имеют встроенной поддержки функций, а также с компиляторами, которые имеют.
Обычно они используются с прямым кодом C, не часто с кодом C ++, поскольку все компиляторы C ++ поддерживают встроенные функции.
источник
#define inline static
определите свои встроенные функции в заголовке.Я считаю, что это просто соглашение об именах для файла «заголовка», включающего встроенный код. это так, что файлы .h могут содержать определения, а файлы .inl содержат встроенный код, необходимый для шаблонов.
Я не верю, что это что-то большее, чем соглашение об именах, чтобы прояснить цель файла
источник