Skip to content

Instantly share code, notes, and snippets.

@kbridge
Created January 25, 2024 19:11
Show Gist options
  • Save kbridge/0a87efaa692747191a82a61e6043e058 to your computer and use it in GitHub Desktop.
Save kbridge/0a87efaa692747191a82a61e6043e058 to your computer and use it in GitHub Desktop.
RTTI does more than type-checking
#include <iostream>
#include <type_traits>
class Bird
{
public:
virtual ~Bird() = default;
};
class IFly
{
public:
virtual ~IFly() = default;
};
class Swift : public Bird, public IFly
{
};
class Penguin : public Bird
{
};
void perform_various_tests(Bird *bird)
{
std::cout << "---\n";
std::cout << "is a swift: " << static_cast<void *>(dynamic_cast<Swift *>(bird)) << "\n";
std::cout << "is a penguin: " << static_cast<void *>(dynamic_cast<Penguin *>(bird)) << "\n";
// this is where RTTI does more than what we think...
// it handles pointer offsets!
std::cout << "can fly: " << static_cast<void *>(dynamic_cast<IFly *>(bird)) << "\n";
}
void verify_convertible(Bird *bird)
{
std::cout << "---\n";
std::cout << static_cast<void *>(static_cast<Swift *>(bird)) << "\n";
// fails to compile
// std::cout << static_cast<void *>(static_cast<IFly *>(bird)) << "\n";
// will not add offset to pointer if bird == nullptr
std::cout << static_cast<void *>(static_cast<IFly *>(static_cast<Swift *>(bird))) << "\n";
}
int main()
{
Swift swift;
Penguin penguin;
perform_various_tests(&swift);
perform_various_tests(&penguin);
verify_convertible(&swift);
return 0;
}
// https://godbolt.org/z/3P76oxM3K
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment