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?
 
     
    