Hi Dodji, Dodji Seketeli <do...@seketeli.org> writes:
> Boris Kolpackov <bo...@codesynthesis.com> a =C3=A9crit: > > > template <typename T> > > struct wrap > > { > > typedef T w_s; > > }; > > > > typedef wrap<my_s_t>::w_s w_s_t; > > > > Now if I traverse from w_s_t using DECL_ORIGINAL_TYPE I get: > > > > w_s_t->w_s->s > > > > Instead of: > > > > w_s_t->w_s->my_s_t->s_t->s > > Ah. Indeed. We strip typedefs from template arguments because G++ > keeps only one instance of each template specialization. So it chooses > to keep the "canonical" one. In other words wrap<my_s_t> and wrap<s> > ultimately representing the same specialization, G++ only construct one > of them. And it chooses to construct wrap<s> because 's' is the > canonical type here and not "my_s_t". If did choose to keep "my_s_t", > error messages would refer to wrap<my_s_t> even for cases where it > really is wrap<s> that has actually been written by the user. That > would be confusing. I see. I guess this is also the reason why we get verbose error messages like: error: âfooâ is not a member of âstd::vector<std::basic_string<char> >â Instead of: error: âfooâ is not a member of âstd::vector<std::string>â Do you know if there are any plans (or desire) to improve this? Creating a separate tree_node for each instantiation would probably be too wasteful so maybe we could keep only "distinct instantiations", i.e., those that were created using distinct type nodes as template arguments. We could use a hash based on the template node pointer plus all the argument type node pointers to detect duplicates. What do you think? Boris