#include <string>
#include <typeinfo>
#ifdef __GNUG__
#include <cxxabi.h>
#include <cstdlib>
#include <memory>
template < typename T > std:: string type_name( )
{
int status ;
std:: unique_ptr < char [ ] , decltype( & std:: free ) > buffer(
__cxxabiv1:: __cxa_demangle( typeid ( T) .name ( ) , nullptr, 0 , & status ) , & std:: free ) ;
return status== 0 ? buffer.get ( ) : "__cxa_demangle error" ;
}
#else // !defined __GNUG__
template < typename T > std:: string type_name( ) { return typeid ( T) .name ( ) ; }
#endif //__GNUG__
template < typename T > std:: string type_name( const T& ) { return type_name< T> ( ) ; }
#define print_type_name(var) ( std::cout << #var << " is of type " << type_name(var) << "\n\n" )
template < class T> class App{
public :
T var;
App( T arg) : var( arg) { }
} ;
class Test{ } ;
#include <iostream>
#include <vector>
#include <cstring>
int main( ) {
print_type_name( "string" ) ;
print_type_name( 'b' ) ;
print_type_name( 1.1 ) ;
print_type_name( 1 ) ;
App< std:: string > obj( "obj_str" ) ;
print_type_name( obj.var ) ;
App< int > obj2( 1 ) ;
print_type_name( obj2.var ) ;
Test o;
App< Test> obj3( o) ;
print_type_name( obj3.var ) ;
print_type_name( obj3) ;
std:: vector < int > vector ;
print_type_name( vector) ;
print_type_name( vector.rbegin ( ) ) ;
print_type_name( std:: strcat ) ;
print_type_name( & std:: strcat ) ;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVpbmZvPgoKI2lmZGVmIF9fR05VR19fCgogICAgI2luY2x1ZGUgPGN4eGFiaS5oPgogICAgI2luY2x1ZGUgPGNzdGRsaWI+CiAgICAjaW5jbHVkZSA8bWVtb3J5PgoKICAgIHRlbXBsYXRlPCB0eXBlbmFtZSBUID4gc3RkOjpzdHJpbmcgdHlwZV9uYW1lKCkKICAgIHsKICAgICAgICBpbnQgc3RhdHVzIDsKICAgICAgICBzdGQ6OnVuaXF1ZV9wdHI8IGNoYXJbXSwgZGVjbHR5cGUoJnN0ZDo6ZnJlZSkgPiBidWZmZXIoCiAgICAgICAgICAgIF9fY3h4YWJpdjE6Ol9fY3hhX2RlbWFuZ2xlKCB0eXBlaWQoVCkubmFtZSgpLCBudWxscHRyLCAwLCAmc3RhdHVzICksICZzdGQ6OmZyZWUgKSA7CiAgICAgICAgcmV0dXJuIHN0YXR1cz09MCA/IGJ1ZmZlci5nZXQoKSA6ICJfX2N4YV9kZW1hbmdsZSBlcnJvciIgOwogICAgfQoKI2Vsc2UgLy8gIWRlZmluZWQgX19HTlVHX18KCiAgICB0ZW1wbGF0ZTwgdHlwZW5hbWUgVCA+IHN0ZDo6c3RyaW5nIHR5cGVfbmFtZSgpIHsgcmV0dXJuIHR5cGVpZChUKS5uYW1lKCkgOyB9CgojZW5kaWYgLy9fX0dOVUdfXwoKdGVtcGxhdGU8IHR5cGVuYW1lIFQgPiBzdGQ6OnN0cmluZyB0eXBlX25hbWUoIGNvbnN0IFQmICkgeyByZXR1cm4gdHlwZV9uYW1lPFQ+KCkgOyB9CgoKI2RlZmluZSBwcmludF90eXBlX25hbWUodmFyKSAoIHN0ZDo6Y291dCA8PCAjdmFyIDw8ICIgaXMgb2YgdHlwZSAiIDw8IHR5cGVfbmFtZSh2YXIpIDw8ICJcblxuIiApCgp0ZW1wbGF0ZTxjbGFzcyBUPiBjbGFzcyBBcHB7CiAgICBwdWJsaWM6CiAgICAgICAgVCB2YXI7CiAgICAgICAgQXBwKFQgYXJnKSA6dmFyKGFyZyl7fQoKfTsKCmNsYXNzIFRlc3R7fTsKCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNzdHJpbmc+CgppbnQgbWFpbigpewogICAgcHJpbnRfdHlwZV9uYW1lKCJzdHJpbmciKTsKICAgIHByaW50X3R5cGVfbmFtZSgnYicpOwogICAgcHJpbnRfdHlwZV9uYW1lKDEuMSk7CiAgICBwcmludF90eXBlX25hbWUoMSk7CgogICAgQXBwPHN0ZDo6c3RyaW5nPiBvYmooIm9ial9zdHIiKTsKICAgIHByaW50X3R5cGVfbmFtZShvYmoudmFyKTsKCiAgICBBcHA8aW50PiBvYmoyKDEpOwogICAgcHJpbnRfdHlwZV9uYW1lKG9iajIudmFyKTsKCiAgICBUZXN0IG87CiAgICBBcHA8VGVzdD4gb2JqMyhvKTsKICAgIHByaW50X3R5cGVfbmFtZShvYmozLnZhcik7CiAgICBwcmludF90eXBlX25hbWUob2JqMyk7CgogICAgc3RkOjp2ZWN0b3I8aW50PiB2ZWN0b3IgOwogICAgcHJpbnRfdHlwZV9uYW1lKHZlY3Rvcik7CiAgICBwcmludF90eXBlX25hbWUodmVjdG9yLnJiZWdpbigpKTsKCiAgICBwcmludF90eXBlX25hbWUoc3RkOjpzdHJjYXQpOwogICAgcHJpbnRfdHlwZV9uYW1lKCAmc3RkOjpzdHJjYXQgKTsKfQo=
stdout
"string" is of type char [7]
'b' is of type char
1.1 is of type double
1 is of type int
obj.var is of type std::string
obj2.var is of type int
obj3.var is of type Test
obj3 is of type App<Test>
vector is of type std::vector<int, std::allocator<int> >
vector.rbegin() is of type std::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >
std::strcat is of type char* (char*, char const*)
&std::strcat is of type char* (*)(char*, char const*)