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


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


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

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

3 88

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 (Я думаю) имя калечить работает по-разному, который получает вокруг имени столкновения во время ссылки, но за счет значительно раздутого кода.  

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