Unfortunately, this is impossible in the general case. Consider:
template <typename T> void foo(T & t)
{
auto it = t.find(42);
...
}
...
std::map<int, int> m;
std::set<int> s;
...
foo(m);
foo(s);
Admittedly a pointless example, but it shows that there's no way to know what to replace auto with, when dependent on a template argument. std::map
and std::set
, incidentally, contain typedefs of the same name (iterator
) that represent the type of the respective iterator, so typename T::iterator it
would work here, but you can instantiate foo
for a T
that does not have such a typedef.
The numerous typedefs in the standard library classes were added exactly to allow such templates to be written before auto
was invented/re-purposed, and you can do the same thing to deal with a compiler that doesn't have auto
. But it's not something you can automate, at least not without an effort comparable to adding support for auto
to a compiler...
Even when auto
is not dependent on a template type, it is a difficult problem to replace it with something that makes sense to the user and is portable. Take:
std::map<int, int> m;
auto it = m.find(42);
The reasonable replacement for auto
is std::map<int, int>::iterator
, but if you use -Dauto=int
and look at the compiler error messages, you'd replace it with something like std::_Rb_tree_iterator<std::pair<const int, int> >
. That's implementation detail of the standard library, hard to read and obviously not portable -- you don't want that in your code.
In your very example, my compiler (GCC 4.4.6) says:
error: cannot convert __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
to int
in initialization
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…