VS14 CTP – Inheriting constructors

Inheriting constructors is a C++ 11 feature implemented in this CTP. It extends the using declaration to allow a derived class to indicate that it needs to inherit the base class constructors. Here’s a basic example.

struct Base
{
  Base(int){}
};

struct Derived : Base
{
  using Base::Base;
};

void Foo()
{
  Derived d1(10); // uses inherited Derived(int)
  Derived d2; // fails to compile, as Base has no default ctor
}

You’ll get this error message (as of this CTP).

error C2280: 'Derived::Derived(void)': attempting to 
reference a deleted function

Had Base had a default constructor or if the existing int constructor had a default parameter value, it’d have compiled fine.

struct Base
{
  Base(int = 1, int = 2){}
  Base(string){}
};

struct Derived : Base
{
  using Base::Base;
};

void Foo()
{
  Derived d1;
  Derived d2(10);
  Derived d3(10,10);
  string s;
  Derived d4(s);
}

All of those instantiations compile file. You can specify multiple using declarations if you have multiple base classes.

struct Base1
{
  Base1(int){}
};

struct Base2
{
  Base2(int, int){}
};

struct Derived : Base1, Base2
{
  using Base1::Base1;
  using Base2::Base2;
};

void Foo()
{
  Derived d1(1), d2(1, 1);
}

With multiple base classes, you need to make sure there aren’t any constructor clashes. Example:

struct Base1
{
  Base1(){}
  Base1(int){}
};

struct Base2
{
  Base2(){}
  Base2(int){}
  Base2(int, int){}
};

struct Derived : Base1, Base2
{
  using Base1::Base1;
  using Base2::Base2;
};

void Foo()
{
  Derived d1(1), d2(1, 1);
}

This won’t compile.

error C3882: 'Base2::Base2': constructor has already 
been inherited from 'Base1'

The fix is to explicitly declare that constructor in Derived.

struct Derived : Base1, Base2
{
  using Base1::Base1;
  using Base2::Base2;

  Derived(int){}
};

Inheriting constructors work with templates too.

template<class T> struct Derived : T
{
  using T::T;
};

struct Base1
{
  Base1(int){}
};

struct Base2
{
  Base2(int, int){}
};

void Foo()
{
  Derived<Base1> d1(10);
  Derived<Base2> d2(10, 11);
}

This feature will save you from the time and effort required with typing explicit derived constructors by having the compiler generate those for you (making it less error prone as well).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s