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

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


edit: Я хотел бы принять оба ответа, но это невозможно. Чтобы закрыть проблему, я принимаю ответ phresnel, потому что он получил большинство голосов, и он формально прав, но, как я упоминал в комментариях, я рассматриваю Puppy и Компонент 10 отвечает как правильные, с другой точки зрения.

Проблема заключается в семантике С++, которая не является строгой в случае ключевого слова inline и вставки. phresnel говорит "напишите в строке, если вы это имеете в виду", но то, что на самом деле подразумевается под inline, не ясно, поскольку оно эволюционировало от своего первоначального значения до директивы, которая "останавливает компиляторы, обвиняющие нарушения ODR", как Puppy.

Ответ 1

Это не имеет значения. И нет, не каждый шаблон функции 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 С++: Полное руководство).

Ответ 2

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

Ответ 3

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

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

Marshall Cline объясняет это здесь лучше, чем я могу.