Below is the working code, It has name()
member function which gives the name of the object type-
#include <iostream>
#include <typeinfo>
int main()
{
int i {1};
std::cout << typeid(i).name() << '\n';
double f {3.14};
std::cout << typeid(i).name() << '\n';
std::cout << typeid(i + f).name() << ' ' << i + f << '\n';
return 0;
}
This is not working... Why?
#include <iostream>
#include <typeinfo>
int main()
{
int i {1};
std::cout << typeid(i) << '\n';
double f {3.14};
std::cout << typeid(i) << '\n';
std::cout << typeid(i + f) << ' ' << i + f << '\n';
return 0;
}
As the saying goes, "this behavior is by design".
In the early days of C++, there was quite a bit of enthusiasm for adding implicit behavior that was supposed to sort of "read the programmer's mind", and do what they (presumably) intended, instead of exactly what the code said.
That got a little out of hand in a few cases, such as the rather notorious specialization of std::vector<bool>
, which is different from std::vector<any-other-type>
in ways that can create pretty significant difficulties.
That led to the pendulum swinging toward the opposite extreme, and requiring the programmer to be 100% explicit about everything.
All that having been said, if you really prefer not to add the .name()
every time you insert a std::type_id
into a stream, you can add an overload to handle it on your own:
#include <iostream>
#include <typeinfo>
std::ostream &operator<<(std::ostream &os, std::type_info const &t) {
return os << t.name();
}
namespace foo {
class bar {
};
}
int main() {
foo::bar f;
std::cout << typeid(f) << "\n";
}
Some will undoubtedly find this a horrible idea. Others will think it should have been there all along, since the behavior seems obvious. It's up to you to decide whether you think it's worthwhile or not.