Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace auto keyword with deduced type (clang or VS2010)

Has anyone written a script, plugin, or executable that replaces each instance of 'auto' with the compiler-deduced type? I need to port some C++11 code that uses auto all over the place.

Clang is my first candidate. Has anyone modified it to do something like this?

An alternative is to parse the errors from a compiler as the expected type might be in the error output. I could -Dauto=int and possibly get back "could not convert std::vector<int>::iterator to 'int'"

like image 758
Cat Zimmermann Avatar asked Jan 20 '12 01:01

Cat Zimmermann


1 Answers

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

like image 183
cvoinescu Avatar answered Oct 04 '22 05:10

cvoinescu