2012-01-20 9 views
11

Czy ktoś napisał skrypt, wtyczkę lub plik wykonywalny, który zastępuje każdą instancję "auto" typem wydedytowanym przez kompilator? Muszę portować trochę kodu C++ 11, który używa auto w całym miejscu.Zastąpienie słowa kluczowego auto wypowiedzianym typem (klang lub VS2010)

Clang jest moim pierwszym kandydatem. Czy ktoś zmodyfikował go, aby zrobić coś takiego?

Alternatywą jest analiza błędów z kompilatora, ponieważ typ oczekiwany może występować w wyniku błędu. Mogłem -Dauto=int i ewentualnie wrócić "could not convert std::vector<int>::iterator to 'int'"

+5

Mało prawdopodobne. Mamy tendencję do łączenia oprogramowania z C++ 11, a nie z C++ 11. –

+0

Nie jest to możliwe - nie w szablonach, których typ zależy od parametrów szablonu. – sellibitze

+1

Ale o ile mi wiadomo, VisualStudio jest na tyle sprytny, by powiedzieć ci typ, jeśli umieścisz kursor nad zmienną za pomocą myszy - chyba że zależy to oczywiście od parametrów szablonu. – sellibitze

Odpowiedz

8

Niestety, jest to niemożliwe w ogólnym przypadku. Rozważmy:

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); 

Wprawdzie bezcelowe przykład, ale pokazuje, że nie ma sposobu, aby wiedzieć, czego się zastąpić automatyczny z, gdy zależy od szablonu argumentu. std::map i std::set, nawiasem mówiąc, zawierają typedef o tej samej nazwie (iterator), które reprezentują typ odpowiedniego iteratora, więc typename T::iterator it będzie działać tutaj, ale można utworzyć egzemplarz foo dla T, który nie ma takiego typu.

Liczne typedefs w standardowych zajęciach bibliotecznych dodano dokładnie, aby umożliwić takie szablony być napisany przed auto wynaleziono/re-zamierzył, i można zrobić to samo do czynienia z kompilatora, który nie ma auto. Ale to nie jest coś, co można zautomatyzować, przynajmniej nie bez wysiłku, porównywalnego do dodawania obsługi auto do kompilatora ...

Nawet jeśli auto nie jest zależny od typu szablonu, zastąpienie go przez coś, co ma sens dla użytkownika i jest przenośne. Take:

std::map<int, int> m; 
auto it = m.find(42); 

Rozsądny zamiennik auto jest std::map<int, int>::iterator, ale jeśli używasz -Dauto=int i spojrzeć na komunikaty o błędach kompilatora, można zastąpić go czymś takim std::_Rb_tree_iterator<std::pair<const int, int> >. To jest szczegół implementacji standardowej biblioteki, trudny do odczytania i oczywiście nie przenośny - nie chcesz, aby kod ten zawierał , który jest.

W swojej samym przykład, mój kompilator (GCC 4.4.6) mówi:

error: cannot convert __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > to int in initialization

Powiązane problemy