Как генерируются шаблоны для ссылочных типов? C++

Для начала давайте рассмотрим код с моей проблемой:

#include <iostream>

template<typename T>
void sum(T x)
{
    x += 1;
}

int main()
{
    int a = 4;
    int& x = a;
    sum(x);
    std::cout << x;
}

Что ожидал я: ввиду того, что я передаю ссылку на int, я ожидал, что при выводе типов T станет равным int& и результирующая функция будет похожа на что-то типа этого:

//T = int&
void sum(int& x)
{
    x += 1;
}

Однако вывод программы: 4, а не, как ожидалось, 5. А в связи с чем у меня данный вопрос. На самом cppreference написано следующее:

1) If P is not a reference type,

a) if A is an array type, A is replaced by the pointer type obtained from array-to-pointer conversion;

b) otherwise, if A is a function type, A is replaced by the pointer type obtained from function-to-pointer conversion;

c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction

То бишь, в моем случае я принимаю "not a reference type" (не ссылочную) T. И все что сказано, что будут проигнорированы лишь const-volatile модификаторы или же я не прав? Почему у меня шаблон генерируется именно так? Или же шаблон не может быть ссылочным типом? Встает такой же вопрос, а может ли он быть типом int*?


Ответы (1 шт):

Автор решения: AR Hovsepyan

При генерации шаблона функции тип может быть выведен по аргументу функции. Вы передаете объект некоторого типа, а ссылка просто является другим именем объекта(ссылка не тип), и значит получите функцию

void sum(int x)
{
    x += 1;
}

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

Указатель вы тоже можете передать, тогда выводимым типом будет int*.

P.S. не думаю, что во многих учебниках это не разъясняется...

→ Ссылка