Посмотрите на этот гипотетический заголовочный файл:
template <class T>
class HungryHippo {
public:
void ingest(const T& object);
private:
...
}
Теперь, для a HungryHippo<string>
, имеет смысл, что вы захотите ingest
ссылки на строки - копирование строки может быть очень дорогостоящим! Но при a HungryHippo<int>
это имеет меньшее значение. Передача int
напрямую может быть действительно дешевой (большинство компиляторов сделает это в регистре), но передача ссылки на int
- лишний ненужный уровень косвенности. Это относится также к возвращаемым значениям.
Есть ли способ предложить компилятору "эй, я не собираюсь изменять аргумент, поэтому вы решаете, следует ли передавать по значению или по ссылке, в зависимости от того, что, по вашему мнению, лучше"?
Некоторые вещи, которые могут иметь значение:
- Я могу подделать этот эффект вручную, написав
template <class T, bool PassByValue> class HungryHippo
, а затем специализируясь наPassByValue
. Если бы я хотел получить действительно фантазию, я мог бы даже сделать выводPassByValue
на основеsizeof(T)
иstd::is_trivially_copyable<T>
. В любом случае, это большая часть дополнительной работы, когда реализации будут выглядеть примерно одинаково, и я подозреваю, что компилятор может намного лучше решить, передавать ли значение по своему усмотрению, чем я могу. -
Проект libС++, похоже, решает это, встраивая множество функций, поэтому компилятор может сделать выбор на один уровень вверх, но в этом случае скажем реализацияКак объясняется в комментариях, все функции шаблонаingest
довольно сложна и не стоит вставлять.inline
по умолчанию.