17

Is it possible to declare or not a member variable depending on template condition without using dummy empty type?

Example:

struct empty{};
struct real_type{};

template<bool condition>
struct foo
{
    typename std::conditional<condition, real_type, empty>::type _member;
};
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211

2 Answers2

16

You can derive from a template that has a specialization:

struct real_type { };

template<bool c>
struct foo_base { };

template<>
struct foo_base<true>
{
    real_type _member;
};

template<bool condition>
struct foo : foo_base<condition>
{
};

As a small test:

int main()
{
    foo<true> t;
    t._member.x = 42; // OK

    foo<false> f;
    f._member.x = 42; // ERROR! No _member exists
}
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Great! In this way I won't have "empty" structs in my class when the condition is false – Mircea Ispas May 21 '13 at 15:03
  • @Felics you are trading one kind of empty for another. Not sure why you'd care about an empty `struct` member variable to begin with, but anyways... – Nik Bougalis May 21 '13 at 15:16
  • @NikBougalis not really. When deriving empty structs might be optimized to be really empty, but members must have different addresses and can't be "empty". Also it is better to not have a member that will pollute the name space than having one dummy member. This is done to enable/disable some features and considering I have many features I can obtain any combination just by setting some bool template params instead of writing combinatorial number of classes – Mircea Ispas May 21 '13 at 15:23
  • Sadly, you cannot pass "naked" identifiers to templates, so we cannot write `template struct maybe_member {}; template struct maybe_member {T X;};` Best we can do is with type tags, which introduce a strange syntax and boilerplate for "member" access. – Yakk - Adam Nevraumont May 21 '13 at 15:27
  • @Felics I don't disagree. I just think that it's (likely) that you're worrying over an unsecured third floor exhaust vent when the front door is almost certainly open. – Nik Bougalis May 21 '13 at 15:31
  • @Yakk: I wish there was such a feature (for instance, I would have used it [here](http://stackoverflow.com/questions/14288050/how-to-achieve-dynamic-polymorphism-run-time-call-dispatch-on-unrelated-types)), on the other hand I have a feeling it would bring tons of complications both from the formal and from the concrete viewpoint – Andy Prowl May 21 '13 at 15:40
  • @AndyProwl I did something like this in my "personal" project. Send me you mail and I can send you some code if you want – Mircea Ispas May 21 '13 at 15:57
  • @AndyProwl I think it's no public, I can't see it:) – Mircea Ispas May 22 '13 at 07:18
1

Is it possible to declare or not a member variable depending on template condition without using dummy empty type?

I believe you can also specialize without the derivation. This tested OK under both -std=c++03 and -std=c++11.

template<bool condition>
struct foo;

template<>
struct foo<true>
{
    real_type _member;
};

template<>
struct foo<false>
{
};

It sure would have been nice if the C++ committee gave us what we wanted/needed:

template<bool condition>
struct foo
{
#if (condition == true)
    real_type _member;
#endif
};
jww
  • 97,681
  • 90
  • 411
  • 885