Question

Background:

What I would like to do is something similar to the following (the code does not work):

class A {
public:
  A(TypeX a)
  {
    /* initialize using TypeX */
  }
  A(TypeY a)
  {
    /* initialize using TypeY */
  }
};


class B {
private:
  A a;
  static const TypeX x;
  static const TypeY y;

public:
  B(bool useTypeX)
    : a(useTypeX ? x : y)
  {}
};

TypeX B::x;
TypeY B::y;

This would be my desired code (if the language supported it), but the ternary operator in the initializer-list construction of B::a does not perform the overload resolution for the two disparate types at compile-time (see: https://stackoverflow.com/a/8535301/1689844).

Please note, I only have control over the design of the B class. Class A, TypeX and TypeY are disparate types and out of my control (also, TypeX and TypeY do not share a common base class nor is TypeX able to be converted into TypeY or vice-versa). Also, class A is expensive to initialize (so copy constructors are not feasible).

Question:

I would like to know if anyone knows of a more elegant solution to achieve my desired behavior than the following implementation of class B. Answers that utilize C++11 features are welcome, but I am confined to using C++03 and therefore I will only accept an answer that utilizes C++03 features:

class B {
private:
  SomeSmartPointer<A> a;
  static const TypeX x;
  static const TypeY y;

public:
  B(bool useTypeX)
  {
    // SomeSmartPointer is a smart pointer
    //    which uses reference-counting to
    //    delete allocated memory when the
    //    reference count is 0 and it is
    //    copy-constructable
    if (useTypeX)
    {
      SomeSmartPointer<A> tmp(x);
      a = tmp;
    }
    else
    {
      SomeSmartPointer<A> tmp(y);
      a = tmp;
    }
  }
};

TypeX B::x;
TypeY B::y;
Was it helpful?

Solution

If A is copy constructable (or move constructable, but that's not relevant since you're not using C++11), then you can do

class B {
private:
  A a;
  static const TypeX x;
  static const TypeY y;
  static A initA(bool useTypeX)
  {
    if (useTypeX)
       return A(x);
    else
       return A(y);
  }
public:
  B(bool useTypeX)
    : a(initA(useTypeX))
  {}
};

Edit: Of course, thinking about it, this is just as legal, eliminating the need for an extra function. The key is that you're explicitly creating them. See https://ideone.com/yUIF0Z

B(bool useTypeX) : a( useTypeX ? A(x) : A(y) ) {}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top