在构造函数中 - 有条件地调用构造函数重载成员变量

时间:2013-11-06 20:20:45

标签: c++ constructor ternary-operator c++03 overload-resolution

背景

我想做的是类似于以下内容(代码不起作用):

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;

这将是我想要的代码(如果语言支持它),但是B :: a的初始化列表构造中的三元运算符在编译时不执行两个不同类型的重载解析(请参阅: https://stackoverflow.com/a/8535301/1689844)。

请注意,我只能控制B类的设计。 A类,TypeX和TypeY是完全不同的类型,不受我的控制(同样,TypeX和TypeY不共享公共基类,也不能将TypeX转换为TypeY,反之亦然)。此外,A类的初始化成本很高(因此复制构造函数不可行)。

问题:

我想知道是否有人知道更优雅的解决方案来实现我想要的行为,而不是以下B类实现。使用C ++ 11功能的答案是受欢迎的,但我仅限于使用C ++ 03因此我只接受使用C ++ 03功能的答案:

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;

1 个答案:

答案 0 :(得分:3)

如果A是可复制的(或者可移动构造,但由于你没有使用C ++ 11而不相关),那么你可以做到

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))
  {}
};

编辑:当然,考虑到这一点,这同样合法,无需额外的功能。关键是你明确地创建它们。见https://ideone.com/yUIF0Z

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