Я вижу практическую причину. И это связано с трудностями, вызванными выводом аргументов шаблона. Представьте себе эту гипотетическую функцию:
template<typename T>
void foo(std::forward_list<T> const&, T const&) {}
Что вы получаете за этот вызов?
std::forward_list<double> l;
foo(l, 1);
Ответ заключается в том, что вы получаете ошибку при выводе аргумента шаблона. Согласно одному аргументу T
является двойным, но согласно другому это int. Если бы я написал erase
, я бы также использовал два разных аргумента шаблона, хотя бы для того, чтобы избежать подобных проблем в невинном коде.
Теперь remove
не является шаблоном-членом, это обычный функция-член любой специализации. Таким образом, вы можете написать без проблем:
std::forward_list<double> l;
// later
l.remove(1);
1
является целым числом, оно не соответствует double
, ожидаемому remove
. Однако это не проблема. Потому что remove
является регулярной функцией-членом конкретной специализации, и неявное преобразование возможно.