Попытка ответить на вопрос «почему»: функция
void someFunc(int arg) { /* ... */ }
явно получает свой аргумент по значению.Имея в виду int
, какую семантику вы ожидаете от этой функции?
template<class T> void someFunc(T arg) { /* ... */ }
Я бы также ожидал, что аргумент будет также передаваться по значению.Теперь рассмотрим фрагменты вызова, в первом случае
int i;
int& j = i;
someFunc(j); /* j passed by value. */
, а во втором случае
X a;
X& b = a;
someFunc(b); /* b passed by reference? Luckily not. */
, где вместо подписи шаблона функции
template<class T> someFunc(T& arg) { /* ... */ }
не так много потенциальных недоразумений в момент вызова - аргумент передается по ссылке.В конце концов, это сводится к целым числам, являющимся обычными типами , а ссылки - нет (см. этот пост для недавнего трактата, также охватывающего указатели).