Имеет ли смысл использовать встроенное ключевое слово с шаблонами?
Поскольку шаблоны определены в заголовках, и компилятор может определить, является ли включение функции выгодным, имеет ли это смысл? Я слышал, что современные компиляторы лучше знают, когда встроить функцию, и игнорируют inline
намек.
редактировать: я хотел бы принять оба ответа, но это невозможно. Чтобы закрыть вопрос, я принимаю ответ Френеля, потому что он получил большинство голосов, и он формально прав, но, как я упоминал в комментариях, я считаю ответы Puppy и Компонента 10 также правильными, с другой точки зрения.,
Проблема в семантике C++, которая не является строгой в случае inline
ключевое слово и встраивание. phresnel говорит "напишите inline, если вы это имеете в виду", но что на самом деле означает inline
неясно, поскольку он превратился из своего первоначального значения в директиву, которая, как говорит Пуппи, "прекращает ссоры компиляторов по поводу нарушений ODR".
3 ответа
Это не имеет значения. И нет, не каждый шаблон функции inline
по умолчанию. Стандарт даже явно об этом в явной специализации ([temp.expl.spec])
Иметь следующее:
a.cc
#include "tpl.h"
b.cc
#include "tpl.h"
tpl.h (взято из явной специализации):
#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}
template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif
Скомпилируйте это, и вуаля:
g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status
Не заявляя inline
при выполнении явной реализации также могут возникнуть проблемы.
Итак, подведем итог: для не полностью специализированных шаблонов функций, то есть тех, которые содержат хотя бы один неизвестный тип, вы можете опустить inline
и не получать ошибки, но все же они не являются inline
, Для полных специализаций, то есть тех, которые используют только известные типы, вы не можете опустить его.
Предлагаемое правило: написать inline
если вы имеете в виду это и просто быть последовательным. Это заставляет вас меньше думать о том, стоит или нет только потому, что вы можете. (Это практическое правило соответствует шаблону Вандевурда / Хосуттиса C++: Полное руководство).
Это не имеет значения. Все шаблоны уже inline
- не говоря уже о том, что с 2012 года единственным inline
Ключевое слово заключается в том, чтобы компиляторы не ссорились по поводу нарушений ODR Вы абсолютно правы - ваш компилятор текущего поколения будет знать, что встроить самостоятельно, и, вероятно, может делать это даже между единицами перевода.
Как вы предположили, inline
это подсказка компилятору и ничего более. Он может игнорировать его или, в действительности, встроенные функции, не помеченные как встроенные.
С помощью inline
с шаблонами (плохим) способом обойти проблему, заключающуюся в том, что каждая единица компиляции создаст отдельный объект для того же шаблонного класса, что затем вызовет проблемы дублирования во время соединения. Используя inline
(Я думаю) искажение имени работает иначе, что обходит конфликт имен во время ссылки, но за счет сильно раздутого кода.
Маршалл Клайн объясняет это лучше, чем я.
Вот что говорит стандарт C++:
Встроенный спецификатор должен применяться только к объявлению переменной или функции.