Zero-cost properties with data member syntax : <p>I have (re?)invented this approach to zero-cost properties with data member syntax. By this I mean that the user can write:</p>

<pre><code>some_struct.some_member = var;
var = some_struct.some_member;
</code></pre>

<p>and these member accesses redirect to member functions with zero overhead.</p>

<p>While initial tests show that the approach does work in practice, I'm far from sure that it is free from undefined behaviour. Here's the simplified code that illustrates the approach:</p>

<pre><code>template &lt;class Owner, class Type, Type&amp; (Owner::*accessor)()&gt;
struct property {
    operator Type&amp;() {
        Owner* optr = reinterpret_cast&lt;Owner*&gt;(this);
        return (optr-&gt;*accessor)();
    }
    Type&amp; operator= (const Type&amp; t) {
        Owner* optr = reinterpret_cast&lt;Owner*&gt;(this);
        return (optr-&gt;*accessor)() = t;
    }
};

union Point
{
    int&amp; get_x() { return xy[0]; }
    int&amp; get_y() { return xy[1]; }
    std::array&lt;int, 2&gt; xy;
    property&lt;Point, int, &amp;Point::get_x&gt; x;
    property&lt;Point, int, &amp;Point::get_y&gt; y;
};
</code></pre>

<p>The test driver demonstrates that the approach works and it is indeed zero-cost (properties occupy no additional memory):</p>

<pre><code>int main()
{
    Point m;
    m.x = 42;
    m.y = -1;

    std::cout &lt;&lt; m.xy[0] &lt;&lt; " " &lt;&lt; m.xy[1] &lt;&lt; "\n";
    std::cout &lt;&lt; sizeof(m) &lt;&lt; " " &lt;&lt; sizeof(m.x) &lt;&lt; "\n";
}
</code></pre>

<p>Real code is a bit more complicated but the gist of the approach is here. It is based on using a union of real data (<code>xy</code> in this example) and empty property objects. (Real data must be a standard layout class for this to work).</p>

<p>The union is needed because otherwise properties needlessly occupy memory, despite being empty.</p>

<p>Why do I think there's no UB here? The standard permits accessing the common initial sequence of standard-layout union members. Here, the common initial sequence is empty. Data members of <code>x</code> and <code>y</code> are not accessed at all, as there are no data members. My reading of the standard indicate that this is allowed. <code>reinterpret_cast</code> should be OK because we are casting a union member to its containing union, and these are pointer-interconvertible.</p>

<p>Is this indeed allowed by the standard, or I'm missing some UB here?</p>
