On 7/20/2013 1:03 PM, Andrew Ho wrote:
It's templated so that multiple inheritance doesn't kill the empty base optimization.
With which compiler? I tests using gcc 4.8.1 and as far as I can tell there's no difference between using templated empty_base vs. untemplated empty_base. Even some times with templated empty_base gcc 4.8.1 would not do empty base class optimization using enough multiple inheritance.
VS2012 doesn't appear to do empty base class optimization for multiple inheritance at all, so templated/untemplated also makes no difference here.
In addition to this, I thought empty_base is there to transform the operation into single inheritance anyways. VS2012 and gcc 4.8.1 both seem to be able to handle single inheritance optimizations fine even if empty_base isn't templated.
// can replace with plain old operators and run the same test. // I'm just using operators2 because it's much easier for me to test templated/untemplated empty_base class MyClass : public boost::operators2::addable< MyClass > ,public boost::operators2::subtractable< MyClass > ,public boost::operators2::multipliable< MyClass > ,public boost::operators2::dividable< MyClass > ,public boost::operators2::xorable< MyClass > // comment out to drop size back to sizeof(int) instead of 8 { // commented: gcc fails to perform empty base class optimizations, sizeof(MyA) = 5 // uncommented: gcc appears to work and sizeof(MyA) = sizeof(int) int val;
// ... OP= operators omitted for clarity };
IIRC the first member sharing a base class would break EBO.
i.e.
struct Foo : addable< Foo >
{
// <snip>
};
struct Bar : addable< Bar >
{
Foo foo;
// <snip>
};
Bar bar;
Without the template parameter both Bar and Foo would derive from
addable and the standard would forbid static_cast