Имеет ли смысл использовать встроенное ключевое слово с шаблонами?
поскольку шаблоны определяются в заголовках и компилятор может определить, является ли вставка функции выгодной, имеет ли это какой-либо смысл? Я слышал, что современные компиляторы лучше знают, когда встроить функцию и игнорируют inline
намек.
edit: я хотел бы принять оба ответа, но это невозможно. Чтобы закрыть проблему, я принимаю phresnelответ, потому что он получил большинство голосов, и он формально прав, но, как я уже упоминал в комментарии я считаю щеноки компонент 10ответы как правильные тоже, с другой точки зрения.
проблема заключается в семантике C++, которая не является строгой в случае inline
ключевое слово и встраивание. phresnel говорит "написать inline, если вы это имеете в виду", но что на самом деле подразумевается под inline
не ясно, как он эволюционировал от своего первоначального значения к директиве ,которая "останавливает компиляторы скулить о нарушениях ODR" как щенок говорит.
3 ответа:
это не имеет никакого отношения. И нет, не каждый шаблон функции
inline
по умолчанию. Стандарт даже явно об этом в явной специализации ([temp.обоснуй.спецификации])имеем следующее:
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
с шаблонами используется (плохой) способ обойти проблему, что каждая единица компиляции создаст отдельный объект для того же шаблонного класса, который затем вызовет проблемы дублирования во время ссылки. С помощьюinline
(Я думаю) имя калечить работает по-разному, который получает вокруг имени столкновения во время ссылки, но за счет значительно раздутого кода.Маршалл Клайн объясняет здесь лучше, чем я могу.