Skip to content

Delegating constructors

A feature that I had been waiting a long time for is the ability to delegate constructors. To delegate a constructor means that one constructor can call another to initialise the object. When member object initialisation needed to be shared between constructors, or one constructor was the same as another but with some default arguments, the only way to do this was to either duplicate code or call some common function. Both have their problems, the first being that duplicated code is usually bad, the second being that you throw out any initialisation list advantages that you might get by calling some common function in the body of the constructor. Delegating constructors fixes this.

The syntax is quite simple, you simply call the constructor as the only item in an initialiser list. For example, the default constructor delegates to the integer constructor with the argument 42.

class C
{
  public:

  C(int) { }
  C() : C(42) { }
};

The standard specifies that if a constructor delegates to itself, the program is ill-formed. It also states that in that case no diagnostic is required. Given this example right out of the standard

class C
{
  public:

  C(int) { }
  C() : C(42) { }
  C(char) : C(42.0) { }
  C(double) : C('a') { }
};

int main()
{
  C c('b');
  return 0;
}

Clang complains with the following error

delegate.cpp:8:15: error: constructor for 'C' creates a delegation cycle
      [-Wdelegating-ctor-cycles]
  C(double) : C('a') { }
              ^
delegate.cpp:7:3: note: it delegates to
  C(char) : C(42.0) { }
  ^
delegate.cpp:8:3: note: which delegates to
  C(double) : C('a') { }
  ^
1 error generated.

GCC issues no such error, and compiles. The resulting executable crashes with a stack overflow. So be careful when you delegate constructors that you don’t create an infinite loop, because your compiler might not pick it up.

The tuple

The addition of variadic templates allows an arbitrary-types tuple class to be added to C++. The tuple is essentially an unnamed struct with positional arguments — its elements are accessed through their position rather than by a name. It is a generalised version of the pair class.

Firstly, it is defined in the header <tuple>. To define a tuple, simply use std::tuple with template arguments being the types that you want to be contained in the tuple.

For example, to declare a tuple whose three fields are char, int and string, you would write

typedef std::tuple<char, int, std::string> MyTuple;

Read more…

Code on github

Code that I post here is available on the github repository https://github.com/jarro2783/thenewcpp

You can clone it with

git clone https://github.com/jarro2783/thenewcpp.git

There are standalone examples and actual code like the Variant. Any actual code is in the directory “juice”, and in the namespace Juice. Any new code I make will be added to the namespace Juice to build up the Juice C++11 project. It’s a play on Boost and the Boost Juice brand, and the project’s tagline is Juice up your C++11.

Improving the variant class

Now that alignment support has been implemented in GCC, I can improve the Variant class. At the same time I will discuss a few other improvements that I have made.

Read more…

Generalised attributes

GCC has recently implemented generalised attributes. In this post I will discuss what they are and how they can be useful.

Generalised attributes are an extendible means to specify compiler specific attributes for particular language constructs. Previously these have had compiler specific syntax, and as such, wouldn’t even compile with the wrong compiler. The GNU compiler uses __attribute__, and the Microsoft compiler uses the __declspec keyword.

Attributes are declared by placing an attribute specifier in a declaration. An attribute specifier is said to appertain to a particular entity in the declaration. In other words, the specifier applies to some part of the declaration. The specifier is either an alignas specification, or a list of attributes inside double square brackets ([[]]).

Read more…

Alignment support

GCC has recently implemented alignment support. In this post I will discuss what this is and how you can use it.

There are four additions that are related to alignment support, these are the alignas alignment-specifier, the alignof expression, alignment arithmetic library support and std::align for aligning pointers. I will explain these all individually below.

Alignment is the requirement that the memory address of the first byte of certain types of objects be modulo zero with respect to some integer. For example, int32_t has an alignment of 4, it can only be placed in memory locations divisible by 4.

Alignments are ordered from weaker to stronger or stricter. An alignment that is stricter than another has a larger value. It is said to be stricter because there are less memory locations at which it can be placed, therefore the compiler is stricter in where that object can be placed.

Read more…

TransLucid 0.2 released

TransLucid version 0.2 has been released. With this release comes the ability to replace and delete declarations, intensions as first-class values, and lazy parsing and processing of declarations. It can be downloaded from Sourceforge at http://sourceforge.net/projects/translucid.

You can read all about the latest features at cartesianprogramming.com.

Follow

Get every new post delivered to your Inbox.