
On 25 Nov 2013 at 10:23, Andrey Semashev wrote:
I'm not sure how you got this from my words. No one ever claimed that my proposed boost::type_id<T>() would return an uncopyable object - it returns a const boost::type_index<T>& to a statically constructed instance. One can use the static instance lref directly, take its address, or make a copy like std::type_index can. Under my design, a boost::type_index<T> has sizeof=0 and merely contains a statically constructed const char * shared by all instances. As it is zero sized, it is therefore POD.
Sorry, I completely missed the part where type_index become a template. My comments were made under impression that boost::type_index is not a template and thus cannot have no members and be copyable.
So now it does not erase the type and cannot be used as a key in a container. By all measure it is now a completely different beast than std::type_index, so please, change the naming.
I think we've got to the point where only code explains meaning, so
here is some fully working code for what I have in mind:
class static_string
{
protected:
const char *symbol;
template<class T> static const char *int_storage()
{
static const char mystorage[]=__FUNCDNAME__;
return mystorage;
}
const std::string &int_mangledstorage() const
{
static std::string
mystorage(std::string(".?AV")+std::string(symbol+16,
strlen(symbol)-16-23));
return mystorage;
}
public:
const char *unique_name() const noexcept { return symbol; }
const std::string &mangled_name() const { return
int_mangledstorage(); }
std::string pretty_name() const
{
const std::string &m=mangled_name();
char *temp=__unDNameEx(NULL, m.c_str()+1, 0, malloc, free,
0x2800);
std::string ret(temp);
free(temp);
return ret;
}
};
template<class T> class type_index : public static_string
{
public:
type_index() { symbol=static_string::int_storage<T>(); }
};
MSVC only, but it's very easy to add GCC/clang support. I tested this
using type_indexstd::string and I get:
unique_name=??$int_storage@V?$basic_string@DU?$char_traits@D@std@@V?$a
llocator@D@2@@std@@@static_string@@KAPBDXZ
mangled_name=.?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@
2@@std@@
pretty_name
=std::basic_string
<nitpicking>And its size is not zero anyway.</nitpicking>
Sure. I wasn't explaining myself well, as usual. I did write late last night if it's any excuse.
And what about other platforms? Throwing an exception unconditionally doesn't look like a portable solution.
If a compiler doesn't provide a magic macro for getting function signatures and its typeid() produces a compile error with RTTI off, all bets are off.
At least four people objected to name() returning anything different to what std::type_info::name() does.
And that's what I suggested, isn't it?
I had understood that you want name() to return something compliant with the C++ standard, not what std::type_info::name() precisely returns. Without RTTI and C++11, you cannot return a static const char unique string type identifier which is identical to std::type_info::name() - see my code example above where I slice the front and end off the mangling, plus prepend the correct preamble. In short, for C++98 and 03, you need dynamic memory if you want identical output. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/