Cogs and Levers A blog full of technical stuff

Delegating Constructors in C++11

One of the annoyances I’ve always had with C++ was its lack of elegant handling of constructors. You’d always be forced to swallow the bitter pill of an initializer function that each of your constructors would call. It always felt clunky to me. With C++11 introducing Delegating Constructors, this has all gone now. Take this simple person class, for example. No magic going on here, just a straight forward class and is how we’d implement multiple constructors without the use of an initialiser.

class person {                                                     
  public:        
    /* blank person */
    person(void) 
      : first_name(""), middle_name(""), last_name("") { }                                                          
                      
    /* person with no middle name */                  
    person(const string& fn, const string& ln) 
      : first_name(fn), middle_name(""), last_name(ln) { }                                                          
    
    /* person with full name */
    person(const string& fn, const string& mn, const string& ln) 
      : first_name(fn), middle_name(mn), last_name(ln) { }                                                          
                                                                   
   public:                                                         
      string first_name,                                           
             middle_name,                                          
             last_name;                                            
};                                                                 

Here we have a person class with three constructors all providing their own implementation of how a person object should initialized. This just isn’t nice for a couple of reasons. The first is violation of the DRY principle, we’re repeating ourselves the whole time which goes hand in hand with the second - each constructor initializes the object in its own way. So, the previous answer to this problem was to implement an initializer function which did this work for us.

class person {                                                     
  public:     
    /* initializes the fields of the person class */
    void init(const string& fn, const string& mn, const string& ln) {
      this->first_name = fn; this->middle_name = mn; this->last_name = ln;
    }

    /* blank person */
    person(void) { 
      this->init("", "", "");
    }                                                          
                      
    /* person with no middle name */                  
    person(const string& fn, const string& ln) { 
      this->init(fn, "", ln);
    }                                                          
    
    /* person with full name */
    person(const string& fn, const string& mn, const string& ln) { 
      this->init(fn, mn, ln);
    }                                                          
                                                                   
   public:                                                         
      string first_name,                                           
             middle_name,                                          
             last_name;                                            
};                                                                 

This is better. We’ve got one way to initialize our class, we’re not repeating ourselves. Life is good. But now (in C++11), there’s a better way. Here I’ll show you how to re-implement this class using delegating constructors for the most elegant of solutions.

class person {                                                    
  public:                                                        
    person(void) 
      : person("", "", "") { }                                 
                                                                  
    person(const string& fn, const string& ln) 
      : person(fn, "", ln) { }                                 
                                                                  
    person(const string& fn, const string& mn, const string& ln)
      : first_name(fn), middle_name(mn), last_name(ln) { }     
                                                                  
  public:                                                        
    string first_name,                                          
           middle_name,                                         
           last_name;                                           
};                                                                

We’ve got our most general case constructor (in this case the construct taking in all three names) actually doing the work. The remaining two constructors then just leverage off the functionality defined in the general case. No re-implementation, no initialization function needed.

Defaulted and Deleted Functions in C++11

A default (and more efficient) implementation can be given to your functions using the default keyword. This is the usage of a defaulted function in C++11. In this example, my person class has no written implementation for its constructor or destructor.

class person {
  public:
    person(void) = default;
    virtual ~person(void) = default;
};

The opposite to a defaulted function is a deleted function. The deleted function allows you to remove the implementation of a function by specifying the delete keyword. In C++ this is useful to us if we want to remove the copy constructor from classes that C++ so nicely provides for us. In this example, you can see that we’ve shut down the copy constructor as well as the assignment operator so that copying will no longer be supported.

class person {
  public:
    person(void) = default;
    person(const person&) = delete;
    virtual ~person(void) = default;
    
    person& operator =(const person&) = delete;
};

That’s it for these two features. Simple, but effective.

auto and decltype in C++11

Introduction

Type brevity has never been C++’s strong suit, especially when you start dealing with template classes. It’s just a mess! One of the nifty features that comes along with the C++11 standard is the ability to not need to specify the type. This leaves it as the job for the compiler to complete. This will only be a short post on auto and decltype’s usage.

Usage

To use the auto keyword, just declare your variables as auto. Here are some variables for some simple data types

// simple data types
auto i = 10;
auto ch = 'a';
auto f = 9.2f;

One of the problems I’ve always had, iterating over STL containers is how verbose the type becomes when you declare your iterator. You can use the “auto” keyword here to simplify this greatly now.

// what was this ..
std::vector<std::string>::iterator i = v.begin();

// now becomes this
auto i = v.begin();

That is an improvement out of sight! decltype operates along the same paradigm but instead of operating on a variable’s type, it will take the type of an expression’s result and allow you to bind a name to it.

// a list of names
vector<string> names;

// declare the iterator type for the list
typedef decltype (names.begin()) name_it;

// reuse the declared type
name_it another;

Using auto throughout your code guarantees you that there won’t be any conversions going on to that variable. This in itself is a few layers of performance sapping translation gone! Just the cleanliness of the code is worth its weight in gold!

Viewing RDoc Sets

You can start an internal web server that will serve all of your installed gemsets’ documentation simply by issuing the following command at the console.

$ gem server
Server started at http://0.0.0.0:8808

Point your web browers to the machine on port 8808 and you’re away!

Lambda Expressions with C++11

Introduction

A whole raft of goodness has been delivered with the most recent C++ standard, C++11. One of these features is the inclusion of lambda expressions. Today’s post will take you through the basic syntax for lambdas in C++.

Basic Assignment

You can assign a lambda to a variable quite simply with the following syntax.

#include <iostream>

int main(int argc, char *argv[]) {
  // assignment to an "auto" variable
  auto f1 = [] { std::cout << "Hello, World" << std::endl; };

  f1();

  return 0;
}

I agree that this is a pretty ass-about-face way of printing “Hello, World” to the screen - but it’s done through C++11’s lambda syntax. Passing variables into a lambda expression and getting return values is quite trivial also.

// implicit return types (handled by the complier)
auto add_imp = [] (int a, int b) { return a + b; };

// explicit return types (specified by user)
auto add_exp = [] (int a, int b) -> int { return a + b };

You can nest lambdas pretty easily also. Heres is a multiply-then-divide example where the division operation is the nested operation. Multiplication occurs at the top-level lambda.

auto muldiv = [] (float a, float x, float y) {
  return [] (float v, float u) {             
    return v / u;                           
  }(a * x, y);                               
};                                            

This syntax also allows you to define higher-order functions, so that you can return function object back to the caller for later use. Here, I’ve made a multiplier factory. You give it one side of the multiplication and it’ll hand you back a function that will multiply by that number.

auto mulBy = [](int x) {
  return [=](int y) { return x * y; };
};

auto mulBy2 = mulBy(2);
auto mulBy10 = mulBy(10);

We’ve done something a little bit different here. You can see that we’ve used a term inside the square brackets for the returned function. C++ having a major focus on performance gives the developer as much flexibility as possible when handling values. The information specified within the square braces tells the lambda closure how to handle variables referenced within.

Handling outside state within a lambda

The developer describes to the lambda how she wants variables captured by making specifications within the square brackets. Some examples of what you might see look like this.

Specification Meaning
[] Don’t capture anything
[&] Capture any variable by reference
[=] Capture any variable used making a copy of it
[=, &x] Capture any variable used making a copy of it except for x. Capture x by reference.
[y] Capture y by making a copy but nothing else.
[this] Capture the enclosing class’ pointer

So, we can be quite specific in telling the compiler how we want referenced variables handled within our lambda closure. Finally, I want to present some code on using lambdas with existing constructs. In this example, I’ll reduce a list of integers by accumulating them into a variable referenced outside of a closure.

#include <iostream>                              
#include <vector>                                
#include <algorithm>                             

int main(int argc, char *argv[]) {               

  // vector to reduce
  std::vector<int> l;                           
  l.push_back(1);                               
  l.push_back(2);                               
  l.push_back(3);                               

  // reduced result
  int i = 0;                                    

  // reduction by accumulation
  std::for_each(l.begin(), l.end(),             
    [&i](int n) { i += n; }                    
  );                                            

  std::cout << "reduced to: " << i << std::endl;

  return 0;                                     
}                                                

You can see that is is quite a fluent style for writing lambdas. This post only scratches the surface. Applying these in a real project is going to be key to discovering the depths of lambdas, but they’re alive and well in C++(11) land, that’s for sure.