2

Possible Duplicate:
Generating Structures dynamically at compile time

I am now facing a situation where I want a derived class to inherit from either Base1 or Base2 depending on a condition (in C++03). This means, I want to implement something like:

// pseudo-C++ code
class Derived : public
    if(condition) Base1    // inherit from Base1, if condition is true
    else Base2             // else inherit from Base2
{ /* */ };

This is likely not a good design, but the real world is not perfect.

I have searched here for an answer, but I do not want to use a preprocessor directive Problems with ifdef based inheritance in C++.

How else could I achieve this?

Community
  • 1
  • 1
Masked Man
  • 1
  • 7
  • 40
  • 80
  • 1
    care to explain why the downvotes for "sharing my knowledge with the community" after not finding it here? – Masked Man Dec 08 '12 at 17:30
  • http://en.cppreference.com/w/cpp/types/conditional (But I don't really see a reason for downvotes here. I do hope you've read all the answers to the linked question thoroughly though.) – Mat Dec 08 '12 at 17:31
  • I can understand downvotes to the answer, but why downvotes to the question? It looks like if I had just asked the question without answering it, I wouldn't have got any downvotes (and I might even have got _upvotes_). I really did not know about `std::conditional` and did not find it after searching for `conditional inheritance from either of two base classes` either here or on the internet, what's wrong with asking? – Masked Man Dec 08 '12 at 17:37
  • Duplicate of [Generating Structures dynamically at compile time](http://stackoverflow.com/questions/11376149/generating-structures-dynamically-at-compile-time) and [Is there a standard construct for 'choose'?](http://stackoverflow.com/questions/6397734/is-there-a-standard-construct-for-choosebool-typename-typename) and [Conditional variable declaration](http://stackoverflow.com/questions/6827373/conditional-variable-declaration) – David Heffernan Dec 08 '12 at 17:37
  • Since this is a duplicate of so many other questions here, you may as well delete it in my view. I don't see the benefit to the community. – David Heffernan Dec 08 '12 at 17:40
  • Ah, I see it now. This was not a C++11 question. If you still insist this doesn't have any value, I will delete it. Thanks for pointing out those other posts. – Masked Man Dec 08 '12 at 17:44
  • Well, I don't see that it's not a C++11 question. You didn't say otherwise. But that's not really the point. It's still a duplicate of many other questions. The fact that many of the answers involve std::conditional is a property of the answer. And not the question. For pre C++11 you have boost::conditional. – David Heffernan Dec 08 '12 at 17:46
  • Oh, my apologies about that. Now added the C++03 tag, and also included it within the post. – Masked Man Dec 08 '12 at 17:47

1 Answers1

4

I figured out the solution using templates and partial specialization. The below code does the trick:

// provide both the required types as template parameters
template<bool condition, typename FirstType, typename SecondType>
class License {};

// then do a partial specialization to choose either of two types 
template<typename FirstType, typename SecondType>
class License<true, FirstType, SecondType> {
public:    typedef FirstType TYPE;     // chosen when condition is true
};

template<typename FirstType, typename SecondType>
class License<false, FirstType, SecondType> {
public:    typedef SecondType TYPE;    // chosen when condition is false
};

class Standard {
public:    string getLicense() { return "Standard"; }
};

class Premium {
public:    string getLicense() { return "Premium"; }
};

const bool standard = true;
const bool premium = false;

// now choose the required base type in the first template parameter
class User1 : public License<standard, Standard, Premium>::TYPE {};
class User2 : public License<premium, Standard, Premium>::TYPE {};

int main() {
    User1 u1;
    cout << u1.getLicense() << endl;   // calls Standard::getLicense();
    User2 u2;
    cout << u2.getLicense() << endl;   // calls Premium::getLicense();
}

The syntax looks unclean, but the result is cleaner than using preprocessor directive.

Masked Man
  • 1
  • 7
  • 40
  • 80