Проблема с шаблонным аргументом-коллекцией (не конвертируется неявно в std::string)

Пишу алгоритм на коллекциях, на вход в своих нуждах планирую подавать std::vector либо std::string, шаблонизировал тип входной коллекции:

template<T>
void Foo(const T &mas)
{
    int n = mas.size();
    // ...
}

Такой код не работает для следующего вызова:

Foo("abc");

Это логично, потому что шаблон выводит тип const char[4], а не std::string. Что сделать, чтобы по-прежнему иметь возможность передачи в функцию вектора, но при этом чтобы при вышеуказанном вызове аргумент конвертировался в std::string ?

Я думал сделать специализацию шаблона для std::string, но вывод он сначала выводит тип аргумента и компиляция падает (вместо того, чтобы сначала взять специализацию, и попробовать сконвертировать аргумент).


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

Автор решения: Croessmah

Можете добавить перегрузку:

inline auto Foo(const char * mas)
{
    return Foo<std::string>(mas);
}
→ Ссылка
Автор решения: bipll

Еще можно сделать #include <iterator>, а внутри Foo все вызовы mas.size(), mas.begin() etc. заменить на std::size(mas), std::begin(mas), etc.

Будет работать для строк, векторов, массивов, чего угодно.

→ Ссылка
Автор решения: AR Hovsepyan

Во первых нет таково template<T> синтаксиса... Нужно:

template<typename T> //или <class T>
void Foo(const T& mas)
{
    int n = mas.size();    
    // ...
}  

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

template <std::size_t N>
void Foo(const char(&array)[N]) {
    int n = strlen(array);
    //...    
}

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

template <std::size_t N>
void Foo(const char(&array)[N]) {
    Foo(std::string(array));
    //или
    Foo<std::string>(array);
}
//или же как в ответе от  Croessmah

Теперь можете вызывать функцию Foo("abc");

→ Ссылка