Чтобы ответить на ваш реальный вопрос, проблема с шаблонами заключается в том, что компилятор должен иметь возможность выяснить, какой тип T
только из вызова функции.Он не может этого сделать, потому что T
никогда не используется напрямую и, конечно, не в сигнатуре функции (исключая тип возвращаемого значения).
Небольшое улучшение
Один из подходов заключается в явномэто при звонке, например median<std::vector<double>::iterator, double>(mvvec.begin(), myvec.end());
, но это довольно громоздко.Лучшим вариантом было бы поменять местами порядок RandomIterator
и T
в объявлении шаблона, чтобы можно было просто указать тип возвращаемого значения: median<double>(myvec.begin(), myvec.end());
Лучшее улучшение
Однако,в C ++ 11 и позже вы можете сделать лучше.Удалите class T
в шаблоне и используйте auto, указав значение value_type итератора, если необходимо: auto median(RandomIterator b, RandomIterator e) -> decltype(*b)
Возможно, вы обнаружите, что decltype не нужен.Однако вы также должны быть уверены, хотите ли вы вернуть значение или ссылку - есть плюсы и минусы в каждом случае, поэтому я не могу решить за вас.
Лучший подход
Однако,Ваша функция необычна тем, что она работает с диапазоном (пара итераторов), но возвращает значение.Большинство алгоритмов STL возвращают итератор, потому что они не могут быть уверены, безопасно ли разыменовывать его или нет.Предположим, вы передали begin () и end (), например, из пустого вектора.Возвращая итератор, вызывающая сторона принимает решение о разыменовании (или нет).Это также решает проблему возврата значения или ссылки.В этом случае вызов просто median(mvvec.begin(), myvec.end());
- добавьте deference, если вам нужно.
Уточнение алгоритма
b
и e
должны быть итераторами произвольного доступа, так как вы звоните на std::sort
.Однако счет рассчитывается неэффективно.Попробуйте просто использовать auto count = e - b;
и auto mid = count / 2;
Использование auto
даст вам правильный diff_type, который не всегда совпадает с int.Обычно это ptrdiff_t, но хороший код итератора не должен предполагать даже этого.Если вы не можете использовать auto
, тогда typename std::iterator_traits<RandomIterator>::difference_type
- правильный тип для использования.