The first class will be used for private inheritance in order to ensure the exact same layout. This should make casting safe.
#include <iostream>
#include <string>
struct data_base
{
data_base( int i, std::string&& s ) noexcept
: i_{ i }
, s_{ std::move( s ) }
{}
int i_;
std::string s_;
};
In this trivial example, I print the int
data member first followed by the std::string
data member for instances of data<true>
.
template<bool = true>
struct data : private data_base // inherits
{
data( int i, std::string&& s ) noexcept
: data_base( i, std::move( s ) )
{}
void print()
{
std::cout << "data<true> - " << i_ << s_ << '\n';
}
};
However, the data<false>
prints the std::string
data member first, followed by the int
data member.
template<>
struct data<false> : private data_base
{
void print()
{
std::cout << "data<false> - " << s_ << i_ << '\n';
}
};
Example:
int main()
{
data<true> d{ 5, "abc" };
d.print();
( ( data<false>& )d ).print();
}
Demo: http://coliru.stacked-crooked.com/a/8b1262afe23dc0a2
As the demo shows, even with the -fstrict-aliasing
flag on, there's no warnings.
Now, since they have the same layout, I thought that I could just cast between the two types in order to get a different kind of static polymorphism; without the cost of a virtual function call.
Is this usage safe or am I triggering undefined behaviour?