default – it’s not (just) syntactic sugar

One of the arguably more obvious features introduced in C++11 is the ability to specify keyword default for special member functions. The default keyword instructs the compiler to define the function as if it implicitly would have. In the case of a copy constructor and a POD class, the compiler would define a function to copy each member. The main reason you’d want to do this yourself, as opposed to letting the compiler implicitly declare and define it for you, is if the compiler refuses to do so. For example, if there’s a move operation declared in the class. This is based on the rule of Three (now rule of Five). The idea is that if you declare you own version of the move operator for the class, the default copy constructor may not be appropriate. But this may be old news so let’s move on.

default – it’s not (just) syntactic sugar

At first glance, it may appear that using default is mere syntactic sugar, whereby the compiler is generating simple code which you can easily write yourself (since you’re not lazy and are working out your coding muscles why not?). But there’s a few reasons why you DO want to use default instead of implementating your own special functions:

At first glance, it may appear that using default is mere syntactic sugar, whereby the compiler is generating simple code which you can easily write yourself (since you’re not lazy and are working out your coding muscles why not?). But there’s a few reasons why you DO want to use default instead of implementating your own special functions:

  1. Maintenance: If you add a new member variable, having the compiler generate the default implementation means you reduce the amount of code to update. This is especially true if you have a class with no members, and you declaration would be {}. In that case, still declaring it default is not only consistent, it also saves us from updating the code when we do add a member.
  2. Efficiency: Allowing the compiler to define the function for you can result in more optimized code if declared default outside the class declaration. From the standard:

“Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base.”


[dcl.fct.def.default / 11.4.2]

For example:

struct MyClassToDefault {
    MyClassToDefault();
};

// not first declaration
MyClassToDefault::MyClassToDefault() = default;


Final Thoughts – More about good practices
As described in the note above and in the code sample, defining your non-trivial functions outside the class declaration is good practice. It keeps your interface stable by keeping your header files from changing and causing your clients full recompilations. So not only does it allow the possibility of code optimization, it will make your clients like you more. Well, they probably won’t realize it, so at least they won’t dislike you more.

Leave a Reply

Your email address will not be published. Required fields are marked *