Специализация шаблонной функции для std::string

112
28 июня 2019, 05:20

Есть шаблонная функция, принимающая аргумент произвольного типа. Хочется сделать специализацию этой функции для строк, но при этом строку передавать не по значению, а по const reference.

Например:

#include <iostream>
template<typename T> void f(T param)
{
    std::cout << "General" << std::endl;
}
template<> void f(const std::string& param)
{
    std::cout << "const std::string&" << std::endl;
}
void g(const std::string& str)
{
    f(str);
}
int main()
{
    std::string str;
    f(str);
    g(str);
}

В данном примере, к сожалению, специализация не работает. Всегда вызывается неспециализированная функция.

Подскажите, пожалуйста, как лучше сделать такую специализацию или перегрузку?

Answer 1

Правила дедукции шаблонных аргументов в обоих вызовах f дедуцируют T == std::string. Поэтому ваша специализация просто не подходит под дедуцированное значение T, т.е. будет использоваться "главный" шаблон. Если вы хотите "поймать" эти вызовы в специализации шаблона, то специализировать его придется для std::string, а не для const std::string &.

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

f<const std::string &>(str);

А если вы сделаете именно перегрузку нешаблонной функцией для const std::string &, а не специализацию шаблона, то вызываться будет в обоих случаях именно перегруженная функция

void f(const std::string& param)
{
  std::cout << "const std::string&" << std::endl;
}
Answer 2

Можете просто в аргумент шаблона передать ссыльку, т.е.

template<typename T> void f(T& param)
{
    std::cout << "General" << std::endl;
}

Остальную часть оставлять как есть

READ ALSO
Логические операторы c++

Логические операторы c++

Начал учить с++, на теме логических операторов после пары минут экспериментов наткнулся на то, что есть некоторые нелогичные моменты у логических...

112
Как преобразовать string в char?

Как преобразовать string в char?

Есть произвольная строка не больше 25 символовНапример "wo1fram" Как преобразовать ее в массив char[255]? Чтобы потом с char можно было работать как...

119
Отфильтровать по дате (стрим)

Отфильтровать по дате (стрим)

Есть список обьектов, у каждого из них есть поле ZonedDateTime createdDate необходимо сделать выборку обьектов за последний год

157
Как загрузить файл в облачное хранилище (Google Drive, Яндекс Диск)?

Как загрузить файл в облачное хранилище (Google Drive, Яндекс Диск)?

В процессе создания телеграмм бота,мне понадобилось загружать файлы, которые отправляют пользователи, в облачное хранилищеВозможно я плохо...

115