36

Consider the following code :

template<bool AddMembers> class MyClass
{
    public:
        void myFunction();
        template<class = typename std::enable_if<AddMembers>::type> void addedFunction();

    protected:
        double myVariable;
        /* SOMETHING */ addedVariable;
};

In this code, the template parameter AddMembers allow to add a function to the class when it's true. To do that, we use an std::enable_if.

My question is : is the same possible (maybe with a trick) for data members variable ? (in a such way that MyClass<false> will have 1 data member (myVariable) and MyClass<true> will have 2 data members (myVariable and addedVariable) ?

Vincent
  • 57,703
  • 61
  • 205
  • 388

2 Answers2

37

A conditional base class may be used:

struct BaseWithVariable    { int addedVariable; };
struct BaseWithoutVariable { };

template <bool AddMembers> class MyClass
    : std::conditional<AddMembers, BaseWithVariable, BaseWithoutVariable>::type
{
    // etc.
};
James McNellis
  • 348,265
  • 75
  • 913
  • 977
34

First off, your code just won't compile for MyClass<false>. The enable_if trait is useful for deduced arguments, not for class template arguments.

Second, here's how you could control members:

template <bool> struct Members { };

template <> struct Members<true> { int x; };

template <bool B> struct Foo : Members<B>
{
    double y;
};
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • +++++1 perfect! Mixin with conditional template parameter – Viet May 19 '13 at 02:53
  • 1
    I found this better than the accepted answer, thanks! – mojo1mojo2 Dec 13 '18 at 04:18
  • One simple way to remember the point "The enable_if trait is useful for deduced arguments, not for class template arguments." is "SFINAE can be used on a member function of a class template which is also a function template but not on a member function of a class template which is not." `template typename std::enable_if::type addedFunction();` will remove the compile time error when `AddMembers = false`. – Hari Jun 28 '23 at 11:57