
On 25 Nov 2013 at 23:35, Andrey Semashev wrote:
Yes, I understood you meant something like that (although your type_index derives from static_string which does contain a data member). But that type_index cannot be used as a key in std::map for instance, and therefore it is not the equivalent for std::type_index which I'm interested in.
You could argue that you can use static_string in containers but what's the point of it if you can already use flyweight<string> or a string_ref with the same success. The point of type_index is not just strings but RTTI, which is in most cases more efficient than strings.
I am still struggling to understand the merit of your argument. All type_info really is is a const char string of the mangled type (if you leave out virtual inheritance, which BTW is simply a linked list of pointers to more mangled type const char strings, so all a dynamic_cast<> does is to iterate strcmp() up/down the chain until it finds the right one). That's RTTI, no more, no less. Both GCC and MSVC internally use strcmp() on those strings when comparing type_info's, including for ordering for use in std::map<>. hash_code() I would also be fairly sure is simply a hash of the mangled type string. Therefore what I proposed is almost the same thing as RTTI, and certainly IS the same thing for use as value types inside containers. The only difference when RTTI is off is that the strings become a bit longer to compare and store, and that's it.
I'll remind you again that std::type_info::name() is not required to return a mangled name, and __func__ is not required either. On a perfectly compliant implementation your mangled_name() would fail and that is not acceptable, IMO.
Unless I misunderstood something, the previous complaints about name() was that it MUST return EXACTLY what std::type_info::name()/raw_name() does. If it can't return EXACTLY what name()/raw_name() does, it must not be there at all. As I have previously discussed more than once now, the use of name()/raw_name() to retrieve the underlying mangled string is a very commonly used idiom. Most type registries use it e.g. the one in Boost.Python because it's the only way you can compare type_info's for equivalence across DLLs. I can certainly see why it is so important that it return the exact same string, and hence why I think any name()/raw_name() not returning EXACTLY what std::type_info does is unwise. My opinion here is to simply leave it out, and let user code subclass their own derived class which implements whatever name() they prefer.
You can provide such a function as an optional extension, with the necessary macros to detect its availability in the client code, but putting it into the core interface of the library is a mistake.
No one is suggesting one would use mangled_name() for anything except where you need to compare a boost::type_index<T> with a std::type_info for equality. There you can compare the strings returned by each for equality - if they are equal, they refer to
If I understand what your argument has been so far, I would disagree with you. I think you don't understand how type_info works under the hood. the
same type.
No they don't. You can never test boost::type_index and std::type_info for equivalence by comparing their names.
You appear to think there can only ever be one const std::type_info& instance per typeid(T) for some type T. You are very, very wrong, and no compiler in recent years thinks so [1]. [1]: Many years ago GCC did assume different type_info instances must always refer to different types. My patch adding -fvisibility support to GCC 4.0 caused multiple type_info instances to be emitted for a type (one per SO), and therefore type_info comparisons since GCC 4.5 now do string comparisons of their containing mangled type string [2]. MSVC has always done a full string comparison to my knowledge. [2]: You probably want proof of this, because plenty of people don't believe me. Look at http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a01071_sourc e.html around line 47. It'll explain the __GXX_MERGED_TYPEINFO_NAMES macro and it has the following sentence "We used to do inline pointer comparison by default if weak symbols are available, but even with weak symbols sometimes names are not merged when objects are loaded with RTLD_LOCAL, so now we always use strcmp by default". Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/