I have some weird problem with templates. When trying to pass a parameterised iterator it complains that no function can be found. The code snippet is here, forget about the functionality, it's using the reference to the templatized iterator what interests me
#include <list>
#include <iostream>
template<typename T>
void print_list_element(typename std::list<T>::iterator& it){
std::cout << *it << std::endl;
}
int main() {
std::list<int> theList;
theList.push_back(1);
std::list<int>::iterator it = theList.begin();
print_list_element(it);
return 0;
}
If you try to compile this with g++ v4.3.2 it complains with a message saying that:
main.cpp:14: error: no matching function for call to 'print_list_element(std::_List_iterator<int>&)'
Is there something wrong with the code I wrote or is that g++ needs more information?
g++ can't figure out which template overload of print_list_element
it should use. If you explicitly specify the template parameter it works:
print_list_element<int>(it);
A better way is to write the function like this:
template<typename Iter>
void print_element(Iter it){
std::cout << *it << std::endl;
}
This will now work for any type of iterator, not just std::list<T>::iterator
. Also, the template type will be deduced correctly from the argument.
I realize that it was a contrived example, but almost always you probably didnt want to pass in list<T>::iterator
to a function anyways. At worst, at least template on ListType so that your code would work with lists with custom allocators.
这是非法的,因为std :: list <T> :: iterator不是标准所称的适当的推导上下文
The other responses are correct, but for completeness I'll just add that, by design, C++ can only deduce template arguments automatically in certain cases , and this isn't one of them.
When you think about it, you'll realise that automatic deduction in this case would lead to an undesirable situation. std::list<T>::iterator
is not a real type, it's just a typedef
alias for a real type (eg it might be T*
) to which it is immediately translated, so the compiler would have to build some sort of "reverse index" in order to map T*
back to std::list<T>::iterator
for automatic deduction of T
to work here. But this mapping would break as soon as another class template was created that had a type member called iterator
that was typedef
ed to T*
-- then the compiler would have two choices of what to translate T*
to, and no way to choose between them. Clearly, any automatic deduction policy that breaks when an unrelated class adds a particular typedef
type member is much too fragile to work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.