Ваши имена параметров в строке template
должны включать любые типы параметров функции или возвращаемых типов. Это означает, что вам нужно упомянуть InputIterator
в вашем списке параметров шаблона. Попробуйте изменить объявление функции на:
template <typename InputIterator>
size_t longestBegin(InputIterator firstCandidates, InputIterator lastCandidates)
Ваша следующая проблема: как компилятор узнает, что такое SequenceT
? Ответ в том, что это результат разыменования InputIterator
. Итераторы, которые не являются указателями, имеют вложенный typedef
с именем reference
, который вам здесь нужен. Добавьте это в начало вашей функции, чтобы компилятор знал, что такое SequenceT
:
template <typename InputIterator>
size_t longestBegin(InputIterator firstCandidates, InputIterator lastCandidates)
{
typedef typename InputIterator::reference SequenceT;
[etc.]
Вы могли бы сохранить SequenceT
в качестве параметра шаблона, но тогда компилятор не мог угадать, что это такое, глядя на аргументы, и вам пришлось бы вызывать свою функцию, набрав, например, например. longestBegin<string>(arguments)
, что здесь не обязательно.
Кроме того, вы заметите, что это не работает, если InputIterator
является указателем - указатели не имеют вложенных typedefs. Таким образом, вы можете использовать специальную структуру std::iterator_traits
из стандартного заголовка <iterator>
, которая может решить эти проблемы для вас:
//(At the top of your file)
#include <iterator>
template <typename InputIterator>
size_t longestBegin(InputIterator firstCandidates, InputIterator lastCandidates)
{
typedef typename std::iterator_traits<InputIterator>::reference SequenceT;
[etc.]
Наконец, если первая строка не всегда самая длинная, вы можете получить доступ к строке после конца ее массива внутри второго цикла for. Вы можете проверить длину строки перед тем, как получить к ней доступ:
//(At the top of your file)
#include <iterator>
template <typename InputIterator>
size_t longestBegin(InputIterator firstCandidates, InputIterator lastCandidates)
{
typedef typename std::iterator_traits<InputIterator>::reference SequenceT;
SequenceT firstString = *firstCandidates;
size_t longestValue = firstString.length();
firstCandidates++;
for(size_t idx = 0; idx < longestValue; idx++)
{
T curChar = firstString[idx];
for(InputIterator curCandidate = firstCandidates;curCandidate != lastCandidates; curCandidate++)
{
if (curCandidate->size() >= idx || (*curCandidate)[idx] != curChar)
return idx - 1;
}
}
return longestValue;
}
Также обратите внимание, что функция возвращает (size_t)(-1)
, если нет общего префикса.