两种类型的构造函数与单个模板?

时间:2014-11-17 19:51:04

标签: c++ templates

问题标题可能是荒谬的,所以让我解释一下我要做的事情!我有这个模板类

template <class TBase>
class A : public TBase
{
public:
  A() { /* some initialization */ }
};

“内部”类可以是以下两种类型之一:

class B1
{// no constructor required
};

class B2
{ 
public:
  B2(int& m) : m_mode(m) { }
protected:
  int& m_mode;
};

请注意,B2有一个引用成员变量,因此它需要一个构造函数初始化列表。创建A<B1>的实例很容易,但是如何制作A<B2>?我显然可以删除引用并使用指针,但我想知道这个谜是否有一个我看不到的简单解决方案?

感谢

5 个答案:

答案 0 :(得分:1)

所有子对象必须以派生构造函数选择的方式构造,并且所有子对象都必须具有可访问的析构函数。

任何既未在ctor-init-list中显式构造也未由类内初始化程序构造的子对象都将默认构造。
(禁止参考。)

因此,您的B2需要获得默认代码,或A需要以所述方式调用现有代码。
由于Atemplate,因此可以选择B2

答案 1 :(得分:1)

您可以专攻A

class B1
{
};

class B2
{
public:
  B2 (int& m) : m_mode (m) {}; 
protected:
  int& m_mode;
};

template <class TBase> class A;

template <> class A <B2> : public B2
{
public:
  A(int& m) : B2 (m) {}
};

template <class TBase> class A : public TBase
{
public:
  A() : TBase () {}; 
};

int main()
{
  int x = 42; 

  A <B1> a1; 
  A <B2> a2 (x);
}

答案 2 :(得分:1)

这是我的C ++ 11方法,使用可变参数模板

template <typename TBase, typename... Args>
class A : public TBase
{
public:
  A(Args... args): TBase(args...) { /* some initialization */ }
};

class B1
{// no constructor required
};

class B2
{ 
public:
  B2(int& m) : m_mode(m) { }
protected:
  int& m_mode;
};

int main()
{
    A<B1> fooA;
    int n = 10;

    A<B2, int> fooB(n);
}

答案 3 :(得分:0)

在许多情况下,根据基类的复杂程度和最终需要的特殊化程度,我宁愿使用类工厂:

class B1
{
};

class B2
{
public:
  B2 (int& m) : m_mode (m) {};
protected:
  int& m_mode;
};

class B1Factory
{
public:
  B1 Make () const { return B1(); }
};

class B2Factory
{
public:
  B2Factory (int& ref) : mRef (ref) {};
  B2 Make () const { return B2 (mRef); }
private:
  int& mRef;
};

template <class TBase> class A : public TBase
{
public:
  template <typename Factory> A (const Factory& fac)
  :
    TBase (fac.Make())
  {
  }
};

int main()
{
  int x = 42;

  A <B1> a1 (B1Factory());
  A <B2> a2 (B2Factory (x));
}

请注意,此处不需要专门化A,这意味着减少了代码重复。这对DRY代码很有用。

答案 4 :(得分:0)

没什么大不了的,B可以有​​两个构造函数:

template <class TBase>
class A : public TBase
{
public:
  A() { /* some initialization */ }
  A(int & ri) : TBase(ri) { /* some other initialization */ }
};

未使用的成员只是没有实例化。当然,如果使用错误的ctor,则会出现编译时错误。