Как вы уже знаете, функции не могут быть перегружены только типами возвращаемых значений. Я заметил, что ваши типы являются конструируемыми по умолчанию, поэтому я использовал их в качестве аргументов функции с пустыми значениями по умолчанию, поэтому функция может быть перегружена этим типом аргумента по умолчанию: https://ideone.com/oPSWLC
#include <string>
#include <iostream>
template<typename T>
T get(const std::string &prompt, T ret = T()) {
std::cout << prompt;
std::cin >> ret;
return ret;
}
std::string get(const std::string &prompt) {
std::cout << prompt;
std::string ret;
std::getline(std::cin, ret);
return ret;
}
int main() {
get<int>("int: ");
get<std::string>("string: ");
}
Специализация шаблона для функции возврата строки не требуется, точно совпадающая перегруженная функция имеет более высокий приоритет, чем шаблон функции.