Conditionally instantiate member variable on presence of constexpr definition

Viewed 152

I have a class Foo in a namespace that I would like to have a member variable conditionally defined based on a condition. In C, I would have expressed this using an ifdef, but defines suffer from not being namespace-able. Is there a way to achieve the same effect using constexpr?

The closest I've gotten to is the below, but I'd like to have it such that not having is_field_a_present defined results in Bar::a not being instantiated.

In Foo.h:

#include <config.h>

namespace Foo {
struct Bar {
    struct empty {};
    [[no_unique_address]] std::conditional<is_field_a_present, int32_t, empty>::type a;
};
}

In config.h:

namespace Foo {
    constexpr bool is_field_a_present = false;
}
1 Answers

You might use std::conditional in inheritance:

namespace Foo
{
    namespace detail
    {
        struct empty {};
        struct with_a {int32_t a;}
    }
    
    struct Bar : std::conditional<is_field_a_present, detail::with_a, detail::empty>::type
    {
    };

}

Demo

Note: if you do it for several fields, you should probably use different empty classes (you might "tag" them) to really allow EBO (if your class have several (non tagged) empty, they should have distinct addresses, so use extra byte).

Related