Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using enable_if to optionally add a struct member

Given this template:

template <class A>
struct Something {
    ... // members common to all template instantiations for all A types 
    SpecialType member; // but not this - I want this to be conditional...
}

...I want to use "enable_if" to have the SpecialType member exist conditionally; that is, only when the template is instantiated with A=SpecialCase1 or SpecialCase2 types. In all other cases, I want the SpecialType member to be missing.

In case you're wondering why, this is about optimization - i.e. not carrying useless payload in the struct. I am a newbie in template metaprogramming, but I understand I need "enable_if" and two "is_same" somehow - not sure exactly how, though...

EDIT: Doing it with generic C++ (i.e. without Boost-specifics) would be a plus.

like image 853
ttsiodras Avatar asked Apr 13 '12 11:04

ttsiodras


1 Answers

Well: use a base class.

struct Empty {};

struct SpecialTypeCnt { SpecialType member; };

template <typename A>
struct Something: if_< /* cond */ , SpecialTypeCnt, Empty>::type {
};

Where if_ is defined as:

template <typename, typename, typename E> struct if_ { typedef E type; };

template <typename T, typename E>
struct if_<std::true_type, T, E> { typedef T type; };

(You can also specialize on a boolean)

Now of course, you need to express your condition properly.


Having said that, you should probably not use just a struct. Instead you should use a class which provides the operations that need be applied on member. Then you provide a class Null with a default behavior and a class SomeType with the behavior specific to member.

Otherwise you'll rewrite the condition everywhere you need to "perhaps" modify member, and it gets annoying real quick.

like image 162
Matthieu M. Avatar answered Oct 07 '22 01:10

Matthieu M.