typename vector‹T›::iterator не распознается компилятором

Теперь у меня есть метод шаблона, подобный этому:

template<typename T>
void f(typename vector<T>::iterator it)
{
//implemenation
...
}

int main()
{
vector<int> v;
//initialization of v;
...

f(v.begin());

return 0;
}

Но когда я компилирую как "g++ THIS_FILE -o TARGET_RUNNABLE", компиляция говорит

 no matching function for call to ‘f(std::vector<int>::iterator)’
 template argument deduction/substitution failed:
 couldn't deduce template parameter ‘T’

Я понимаю, что нужно добавить ключевое слово "typename" перед vector::iterator. Но это все равно неправильно. Кто-нибудь знает, как решить эту проблему?


person dong    schedule 17.10.2013    source источник
comment
Вы не можете вывести такие вещи.   -  person chris    schedule 17.10.2013
comment
Вы не можете переносимо вывести тип контейнера из типа итератора. Как правило, можно было бы написать функцию как template<typename It> void f(It it); (и затем по-прежнему использовать f(v.begin())). Если вам нужен тип контейнера, вы должны передать другой аргумент (template<class Cont, class It> void f(Cont&, It);) или явно указать аргумент шаблона template<class Cont, class It> void f(It); f<std::vector<int>>(v.begin());).   -  person dyp    schedule 17.10.2013


Ответы (4)


Ваша функция принимает итератор, но вы пытаетесь передать вектор. Возможно, вы имели в виду f(v.begin()) или что-то в этом роде.

Кроме того, как отмечает @chris, T находится в невыводимом контексте. Это должно быть указано явно, как в f<int>(v.begin());

person Igor Tandetnik    schedule 17.10.2013
comment
сори, это опечатка. это f(v.begin()) в вопросе - person dong; 17.10.2013

Вы передали v, который равен vector<int>, функции f. Вы должны передать итератор f.

Просто переделайте функцию шаблона, чтобы

template<typename Iterator>
void f(Iterator it)
{ 
   // manipulate iterator it
}

тогда вы могли бы позвонить

vector<int> v;

f(v.begin());
person billz    schedule 17.10.2013
comment
Я сожалею, что это опечатка в моем вопросе. На самом деле это действительно f(v.begin()), но не работает. - person dong; 17.10.2013

Проблема в том, что дедукция аргумента шаблона работает примерно с 20 различными формами, но не с формой typename Foo<T>::Bar. Причина в том, что существует бесконечно много Foo, и каждый из них может иметь вложенный тип Bar, который соответствует вашему. Компилятор не может искать их все.

Хорошим примером такой проблемы является сравнение std::vector<T>::const_iterator и std::vector<const T>::const_iterator, которые вполне могут быть одного и того же типа.

Поэтому он называется невыводимым контекстом. Вы должны четко указать, какой шаблон вы хотите.

person MSalters    schedule 17.10.2013
comment
Это на самом деле не отвечает на вопрос (т.е. как исправить?) - person rubenvb; 17.10.2013

Один из способов исправить ошибку компилятора — явно указать параметр шаблона.

f<int>(v.begin());
person R Sahu    schedule 13.08.2014