Какой смысл использовать ключевое слово inline с шаблонами?

поскольку шаблоны определены в заголовках, и компилятор может определить, является ли вставка функции выгодной, имеет ли это смысл? Я слышал, что современные компиляторы лучше знают, когда вставлять функцию и игнорируют inline намек.


edit: я хотел бы принять оба ответа, но это невозможно. Чтобы закрыть вопрос, который я принимаю phresnelответ, потому что он получил большинство голосов, и он формально прав, но, как я уже упоминал в комментарии я считаю щеноки компонент 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

скомпилируйте это, et voila:

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 если вы имеете в виду это и просто быть последовательным. Это заставляет вас меньше думать о том, нужно или нет просто потому, что вы можете. (Это эмпирическое правило соответствует Vandevoorde's / Josuttis Шаблон C++: Полное Руководство).


это не имеет значения. Все шаблоны уже inline- не говоря уже о том, что по состоянию на 2012 год, только использовать inline ключевое слово, чтобы остановить компиляторы нытье о нарушениях ODR. Вы абсолютно правы - ваш компилятор текущего поколения будет знать, что встроить самостоятельно, и, вероятно, может сделать это даже между единицами перевода.


как вы и предлагали,inline - это подсказка компилятору и ничего более. Он может игнорировать его или, действительно, встроенные функции, не отмеченные inline.

используя inline с шаблонами, которые были (плохим) способом обойти проблему, что каждая единица компиляции создаст отдельный объект для того же шаблонного класса, который затем вызовет проблемы дублирования во время ссылки. Используя inline (Я думаю) имя mangling работает по-другому, который обходит имя clash во время ссылки, но за счет сильно раздутого кода.  

Маршалл Клайн объясняет здесь лучше, чем я могу.