Такое объявление функции эквивалентно шаблону функции:
template<typename T>
void print(T x) {
std::cout << x << std::endl;
}
При компиляции будут созданы 3 функции
print<int>, print<const char*>, print<char>
.
Кстати, предупреждая возможные будущие ошибки: при таком использовании auto, функция print принимает все аргументы
по значению, а в подобных ситуациях часто лучше по ссылке. С этой точки зрения более корректным может быть одно из следующих объявлений:
void print(const auto& x) {
std::cout << x << std::endl;
}
void print(auto& x) {
std::cout << x << std::endl;
}