C++17: std::any

When trying to implement something that will store a data value of an unknown type (in order to be as generic as possible, for example), we had these possibilities before C++17:

  • Having a void* pointer to something that will be assigned in runtime. The problem with this approach is that you leave the complete responsability of handling the lifetime of the thing poìnted by this void pointer to the user of our code. Very error prone.
  • Having a union with a limited set of types available.
  • Having a base class (e.g. Object) and store pointers to instances derived from such class (à la Java).
  • Having an instance of template typename T (for example). Good approach, but in order to be useful and generic, we need to propagate the typename T in all the generic code that will use ours. Probably verbose.

So, let’s welcome to std::any.

std::any, as you already guess it, is a template class shipped in C++17 and implemented in <any> that can store a value of any type, so, these lines are completely valid:

std::any a = 123;
std::any b = "Hello";
std::any c = std::vector<int>{10, 20, 30};

Obviously, this is C++ and you, as user, need to know the type of the thing you stored in an instance of std::any, so, to retrieve the value stored, you need to perform an any_cast as in this code:

#include <any>
#include <iostream>

int main()
{
    std::any number = 150;
    std::cout << std::any_cast<int>(number) << "\n";
}   

If you try to cast the value stored in an instance of std::any, a std::bad_any_cast exception is thrown. For example, if you try to cast that number to a string, you will get this runtime error:

terminate called after throwing an instance of 'std::bad_any_cast'
  what():  bad any_cast

If the value stored in an instance of std::any is an instance of a class or struct, the compiler will make sure the destructor of such value will be invoked when the instance of std::any will go out of scope.

Other really nice thing about std::any is that you can replace the existing value stored in an instance of it, for other value of any other type, for example:

std::any content = 125;
std::cout << std::any_cast<int>(content) << "\n";

content = std::string{"Hello world"};
std::cout << std::any_cast<std::string>(content) << "\n";

About lifetimes

Let’s consider this class:

struct A
{
  int n;
  A(int n) : n{n} { std::cout << "Constructor\n"; }
  ~A() { std::cout << "Destructor\n"; }
  A(A&& a) : n{a.n} { std::cout << "Move constructor\n"; }
  A(const A& a) : n{a.n} { std::cout << "Copy constructor\n"; }
  void print() const { std::cout << n << "\n"; }
};

This class stores an int, and print it out with “print”. I wrote constructor, copy constructor, move constructor and destructor with messages that will tell me when the object will be created, copied, moved or destroyed.

So, let’s create a std::any instance with an instance of this class:

std::any some = A{4516};

This will be the output of such code:

Constructor
Move constructor
Destructor
Destructor

Why two constructors and two destructors are invoked if I only created one instance?

Because the instance of std::any will store a copy (ok, in this case a “moved version”) of the original object I created and, though in my example can be trivial, in a complex object it cannot be.

How to avoid this problem?

Using std::make_any.

std::make_any is very similar to std::make_shared in the way that it will be in charge to create the object instead of copying/moving ours. The parameters passed to std::make_any are the ones you would pass to the object’s constructor.

So, I can modify my code to this:

auto some = std::make_any<A>(4517);

And the output will be:

Constructor
Destructor

Now, I want to invoke to the method “print”:

auto some = std::make_any<A>(4517);
std::any_cast<A>(some).print();

And when I do that, the output is:

Constructor
Copy constructor
4517
Destructor
Destructor

Why such extra copy was created?

Because std::any_cast<A> returns a copy of the given object. If I want to avoid a copy and use a reference, I need to explicit a reference in std::any_cast, something like:

<code>auto some = std::make_any<A>(4517);
std::any_cast<A&>(some).print();</code>

And the output will be:

Constructor
4517
Destructor

It is also possible to use std::any_cast<T> passing a pointer to an instance of std::any instead of a reference.

In such case, if the cast is possible, will return a valid pointer to a T* object, otherwise it will return a nullptr. For example:

auto some = std::make_any(4517);
std::any_cast<A>(&some)->print();
std::cout << std::any_cast<int>(&some) << "\n";

In this case, notice I am passing a pointer to “some” instead of a reference. When this occurs, the implementation returns a pointer to the target type if the object stored is of the same type (as in the second line) or a null pointer if noy (as in the third line, where I am trying to cast my object of type A to int). Using these overloaded version with pointers avoids to raise an exception and lets you check if the returned pointer is null instead.

std::any is a very nice tool to store things that we, as implementors of something reusable, do not know a priori; it could be used to store for example, extra parameters passed to threads, objects of any type stored as extra information in UI widgets (similar to the .Tag property in Windows.Forms.Control in .NET, for example), etc. Performance wise, std::any needs to store things in the heap and also needs to perform some extra checking to return the values only if the cast is valid, so, it is not as fast as having a generic object known at compile time.

C++20: Concepts, an introduction

I am pretty new doing C++ Concepts, so I will post here the things I will learn while starting to use them.

C++ Concepts are one of these three large features that are shipped with C++20:

  • Concepts
  • Ranges
  • Modules

Basically, C++ Concepts define a set of conditions or constraints that a data type must fulfill in order to be used as a template argument.

For example, I would want to create a function that sums two values and prints the result. In C++17 and older I would code something like this:

template <typename A, typename B>
void sum_and_print(const A& a, const B& b)
{
    std::cout << (a + b) << "\n";
}

And it works properly for types A and B that DO have the operator+ available. If the types I am using do not have operator+, the compiler naïvely will try to substitute types A and B for the actual types and when trying to use the missing operator on them, it will fail miserably.

The way the compiler works is correct, but failing while doing the actual substitution with no earlier verification is kind of a reactive behavior instead of a proactive one. And in this way, the error messages because of substitution error occurrences are pretty large, hard to read and understand.

C++20 Concepts provide a mechanism to explicit the requirements that, in my example, types A and B would need to implement in order to be allowed to use the “sum_and_print” function template. So when available, the compiler will check that those requirements are fulfilled BEFORE starting the actual substitution.

So, let’s start with the obvious one: I will code a concept that mandates that all types that will honor it will have operator+ implemented. It is defined in this way:

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 };

The new keyword concept is used to define a C++ Concept. It is defined as a template because the concept will be evaluated against the type or types that are used as template arguments here (in my case, T and U).

I named my concept “Sumable” and after the “=” sign, the compiler expects a predicate that needs to be evaluated on compile time. For example, if I would want to create a concept to restrict the types to be only “int” or “double”, I could define it as:

template <typename T>
concept SumableOnlyForIntsAndDoubles = std::is_same<T, int>::value || std::is_same<T. double>::value;

The type trait “std::is_same<T, U>” can be used here to create the constraint.

Back to my first example, I need that operator+ will be implemented in types A and B, so I need to specify a set of requirements for that constraint. The new keyword “requires” is used for that purpose.

So, any definition between braces in the requires block (actually “requires” is always a block, even when only a requirement is specified) is something the types being evaluated must fulfill. In my case, “a+b” and “b+a” must be valid operations. If types T or U do not implement operator+, the requirements will not be fulfilled and thus, the compiler will stop before even trying to substitute A and B for actual types.

So, with such implementation, my function “sum_and_print” works like a charm for ints, doubles, floats and strings!

But, what if I have another type like this one:

struct N
{
    int value;

    N operator+(const N& n) const
    {
        return { value + n.value };
    }
};

Though it implements operator+, it does not implement operator<< needed to work with std::cout.

To add such constraint, I need to add an extra requirement to my concept. So, it could be like this one:

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 }
 && requires(std::ostream& os, const T& a)
 {
     { os << a };
 };

The operator && is used here to specify that those requirements need to be fulfilled: Having operator+ AND being able to do “os << a“.

If my types do not fulfill such requirements, I get an error like this in gcc:

<source>:16:5:   in requirements with 'std::ostream& os', 'const T& a' [with T = N]
<source>:18:11: note: the required expression '(os << a)' is invalid
   18 |      { os << a };
      |        ~~~^~~~

That, though looks complicated, is far easier to read than the messages that the compiler produces when type substitution errors occur.

So, if I want to have my code working properly, I need to add an operator<< overloaded for my type N, having finally something like this:

#include <iostream>

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 }
 && requires(std::ostream& os, const T& a)
 {
     { os << a };
 };

template <Sumable A, Sumable B>
void sum_and_print(const A& a, const B& b)
{
    std::cout << (a + b) << "\n";
}

struct N
{
    int value;

    N operator+(const N& n) const
    {
        return { value + n.value };
    }
};

std::ostream& operator<<(std::ostream& os, const N& n)
{
    os << n.value;
    return os;
}

int main()
{
    sum_and_print( N{6}, N{7});
}

Notice that in my “sum_and_print” function template I am writing “template <Sumable a, Sumable b>” instead of the former “template <typename A, typename B>“. This is the way I ask the compiler to validate such type arguments against the “Sumable” concept.


What if I would want to have several “greeters” implemented in several languages and a function “greet” that will use my greeter to say “hi”. Something like this:

template <Greeter G>
void greet(G greeter)
{
    greeter.say_hi();
}

As you can see, I want my greeters to have a method “say_hi“. Thus, the concept could be defined like this one in order to mandate the type G to have the method say_hi() implemented:

template <typename G>
concept Greeter = requires(G g)
{
    { g.say_hi() } -> std::convertible_to<void>;
};

With such concept in place, my implementation would be like this one:

template <typename G>
concept Greeter = requires(G g)
{
    { g.say_hi() } -> std::convertible_to<void>;
};

struct spanish_greeter
{
    void say_hi() { std::cout << "Hola amigos\n"; }
};

struct english_greeter
{
    void say_hi() { std::cout << "Hello my friends\n"; }
};


template <Greeter G>
void greet(G greeter)
{
    greeter.say_hi();
}


int main()
{
    greet(spanish_greeter{});
    greet(english_greeter{});
}

Why would I want to use concepts instead of, say, base classes? Because:

  1. While using concepts, you do not need to use base classes, inheritance, virtual and pure virtual methods and all that OO stuff only to fulfill a contract on probably unrelated stuff, you simply need to fulfill the requirements the concept defines and that’s it (Interface Segregation of SOLID principles would work nice here, anyway, where your concepts define the minimum needed possible constraints for your types).
  2. Concepts are a “Zero-cost abstraction” because their validation is performed completely at compile-time, and, if properly verified and accepted, the compiler does not generate any code related to this verification, contrary to the runtime overhead needed to run virtual things in an object-oriented approach. This means: Smaller binaries, smaller memory print and better performance!

I tested this stuff using gcc 10.2 and it works like a charm.

Deleaker, part 0: Intro

I am testing this nice desktop tool called “Softanics Deleaker” (https://www.deleaker.com/). It was written by Artem Razin and, as you can deduce by its name, it is an application that helps the programmers to find memory leaks on C++, Delphi and .NET applications.

Starting this post, I will post several blog entries about my experiences using it and the features it exposes.

I installed it and installed the Visual Studio extension that ships with the installer. For my tests, I am using Visual Studio 2019 16.4 preview.

In Visual Studio I created a C++ console application and wrote this very simple and correct application:

int main()
{
    std::cout << "Hello World!\n";
    return 0;
}

When I run the local debugger, and since I have installed the Deleaker VS extension, the leaker will load all libraries and symbols of my application and will open a window similar to this one:

I still do not know what all those options mean, but the important thing here is the “No leaks found” message. The filter containing the “266 hidden” items refers to known leaks that Deleaker knows that exist in the Microsoft C Runtime Library.

Now, I will create a very small program too containing a small memory leak:

int main()
{
    for (int i = 0; i < 10; i++)
    {
        char* s = new char{'a'};
        std::cout << *s << "\n";
    }

    return 0;
}

As obviously observed, I am allocating dynamically one byte to contain a character and I am forgetting to delete it. When I debug it, I get this interesting Deleaker window:

Now Deleaker detected my forgotten allocation and says that to me: “ConsoleApplication2.exe!main Line 7”.

As you can see, the “Hit Count” says that the allocation occurred 10 times (because my loop) and it says that 370 bytes leaked on this problem. Though that seems weird because I allocated only 1 byte 10 times, the 370 bytes appear because I compiled my code in Debug Mode and the compiler adds a lot of extra info per allocation. When I changed my compilation to Release Mode, I got the actual 10 bytes in the Size column.

When you click into the information table in the row containing the memory leak information, the Visual Studio editor highlights that line and moves the caret to such position (the new char{‘a’} line , so you realize where you allocated memory that was not released.

And that is it for now.

In next blog entries I will explore how to “Deleak” not so obvious things, how Deleaker behaves with shared pointers, COM objects, shared libraries, templates, virtual destructors and so on :)

Happy 2020!

 

C++ “Hello world”

Ok, the most famous first program on any programming language is the “Hello world” program, so I will explain how to create one in this post.

In my example I will use “g++” in a Linux environment, but “clang++” works exactly the same.

To create a “Hello world” in C++, you need to create an empty file and give it a name with an extension (any name, for example HelloWorld.cpp); “cpp”, “cxx” or “cc” are well-known C++ file name extensions.

The compiler does not verify if the filename is equal to the name of the “class” or anything inside the file; the file can be stored on any folder too, you do not need to create it inside a special folder containing all stuff of a given “package” (à la Java), for example.

So, after creating an empty HelloWorld.cpp, you can open it using any text editor and start to write the following lines of code:

#include <iostream>

int main()
{
  std::cout << "Hello world\n";
}

Save it, open a terminal, go to the folder where your file is located and there, enter this:

g++ HelloWorld.cpp -o HelloWorld

If after entering that command line you do not get any message, BE HAPPY! Your program compiled properly. Otherwise, you did some error in your code and you need to fix it and compile it again.

After compiling it properly, you need to execute the program. In a Linux/Unix environment, you do that writing the name of the program after a ./ :

./HelloWorld

And the program should show:

Hello world

Understanding how all of this worked

The compilation process in C++ has basically three steps:

  1. Passing your program through the "preprocessor"; an entity that performs several text transformations on your code before being compiled.
  2. The actual compilation process, that turns all your code into machine code with several calls to functions that are located in other libraries.
  3. The linking process, that binds the function calls with the actual functions in the libraries the program uses. If you do not specify anything (as in our case), your program will be linked only to the Standard Library that ships with any C++ compiler.

The parts of the program

#include

#include <iostream>

All things that start with "#" are called "preprocessor directives", that are instructions the preprocessor understands and executes.

#include tells to the preprocessor to look for the file named inside quotes or less-than and greater-than and put its content in the place the #include directive was invoked.

If the filename is inside less-than and greater-than characters (as in our case), the preprocessor will look for the file in a previously defined folder the compiler knows about. So, it will look for the file iostream in that folder. In a Linux environment, those files are generally in a path similar to this one (I am using g++ 8.2):

/usr/include/c++/8

If the filename is declared between double quotes, it means the file will be in the current folder or in a folder explictly mentioned while compiling the program.

iostream is the file that contains a lot of code that allows our programs to have data input and output. In our “Hello World”, we will need “std::cout” that is defined in this file.

main function
int main()

When you invoke your program, the operating system needs to know what piece of code it needs to execute. Such piece of code lives inside the function main.

All functions must return something, for example, if you call a function sum that sums two numbers, it must return a value containing the result of the sum. So, the function sum must return an integer value (an int). Some old compilers used to allow the function main() to return “void” (that means: “return nothing”) but the C++ standard specifies the main() function must return an int value.

Anyway, though this function is declared returning an int, if you do not return anything, the compiler does not complain about that and returns a 0. Notice that this behavior is exceptional and it is only allowed for the function main().

The return value of function main() specified if an error occurred or not. 0 means that no error occurred during the program executed; and a non-zero value means that an error occurred. The specific value being returned is completely depending on the programmers design and error mechanisms defined by them.

The program will be executed while the function main() is being executed. When its execution ends, the program automatically ends returning the return value to the Operating System.

The body of any function is declared inside two curly braces.

std::cout
std::cout << "Hello world\n";

std::cout is a pre-existing object that represents the command line output. The “<<" is an operator that basically does, in this case, sends the text "Hello world\n" to the std::cout object, producing an output of such text in the terminal.

The \n character sequence means an end of line.

g++

g++ is the most popular C++ compiler for Unix platforms. These days clang has a lot of popularity and you can replace one to other because clang parameters are completely compatible to the g++ ones.

When you say something like:

g++ HelloWorld.cpp

You are instructing to the g++ compiler to go through all the compilation process for the file “HelloWorld.cpp”. “Go through all the compilation process” in this case means: Running the preprocessor on the file, compiling it, linking it and producing an executable.

Since in this command line in my example above I did not mention the name of the executable file, the g++ command generates a file called “a.out” in the current folder.

To specify the name of the file to be generated, you must invoke g++ with the “-o” option and then the name of the executable file to be generated.

C++: variant

Let’s suppose I have a system that handles students, teachers and crew of a school.

To model that in an object oriented style, I would have a class hierarchy similar to this one:

class person
{
	std::string name;
	
public:
	template <typename String>
	person(String&& name) : name { forward<String>(name) }
	{
	}
	
    virtual ~person() { }
    const string& get_name() const { return name; }
	virtual void do_something() = 0;
};

class student : public person
{
public:
	using person::person;
	
	void do_homework()
	{
		cout << "Need access to Stack Overflow\n";
	}
	
	void do_something() override
	{
		cout << "I am doing something the students do\n";
	}
};

class teacher : public person
{
public:		
	using person::person;

	void teach()
	{
		cout << "This is the unique truth\n";
	}
	
	void do_something() override
	{
		cout << "I am doing something the teachers do\n";
	}
};

class crew : public person
{
public:
	using person::person;
	
	void help_team()
	{
		cout << "I am helping teachers and students\n";
	}
	
	void do_something() override
	{
		cout << "I am doing something crew do\n";
	}
};

And my collection would be defined like this:

map<size_t, person*> people;

where the size_t ID would be the key of the map.

Since I do not want to deal with raw pointers, this would be a better definition:

map<size_t, unique_ptr<person>> people;

Now, I will insert some elements to my collection:

people.insert(make_pair(14, make_unique<student>("Phil Collins")));
people.insert(make_pair(25, make_unique<teacher>("Peter Gabriel")));
people.insert(make_pair(32, make_unique<crew>("Justin Bieber")));

To get the name of person 14, I should do something like:

people.find(14)->second->get_name(); //being 100% sure that person with ID 14 exists

And to do something specific implemented in a derived class, I need to downcast:

static_cast<crew&>(*people.find(32)->second).help_team();

Since C++11, the language has been evolving to a more generic and more template metaprogramming-like paradigm and has been getting away from the classical OOP design where inheritance and polymorphism are amongst the most important tools.

So, how could I implement something similar to the thing shown above without inheritance and polymorphism?

Let me introduce std::variant ! :)

C++17 introduced variant, that is basically a template class where you specify the possible types of the values that the variant instance can store, so, for my example, I could define something like:

using person = std::variant<student, teacher, crew>;

In this line, I am defining an alias person that represents a variant value that can store a student, a teacher or a crew (think on variant to be something like a typesafe union).

So, my map would be defined in this way:

map<size_t, person> people;

And my classes student, teacher, and crew could be defined as follows:

class student
{
	std::string name;
public:
	template <typename String>
	student(String&& name) : name { forward<String>(name) }
	{
	}
	
	const string& get_name() const { return name; }
	
	void do_homework()
	{
		cout << "Need access to Stack Overflow\n";
	}
	
	void do_something()
	{
		cout << "I am doing something the students do\n";
	}
};

class teacher
{
	std::string name;
public:		
	template <typename String>
	teacher(String&& name) : name { forward<String>(name) }
	{
	}
	
	const string& get_name() const { return name; }

	void teach()
	{
		cout << "This is the unique truth\n";
	}
	
	void do_something()
	{
		cout << "I am doing something the teachers do\n";
	}
};

class crew
{
	std::string name;
	
public:
	template <typename String>
	crew(String&& name) : name { forward<String>(name) }
	{
	}
	
	const string& get_name() const { return name; }
	
	void help_team()
	{
		cout << "I am helping teachers and students\n";
	}
	
	void do_something()
	{
		cout << "I am doing something crew do\n";
	}
};

To make my example clean and to demonstrate that I do not need inheritance and polymorphism, notice I am not defining a base class nor I am defining virtual methods at all. Anyway. in real production code the coder could create a base class with no virtual methods and inherit from such class to avoid code duplication.

Notice also I am not using any pointer (raw or smart), so the map will contain actual values, removing one level of indirection and letting the compiler optimize based on that knowledge.

So, let me add some objects to the map:

people.insert(make_pair(14, student { "Phil Collins" }));
people.insert(make_pair(25, teacher { "Peter Gabriel" }));
people.insert(make_pair(32, crew { "Justin Bieber" }));

To get the person with id 14:

auto& the_variant = people.find(14)->second;

To get the “student” inside that variant object, I need to use the function get:

auto& the_student = get(the_variant);
cout << the_student.get_name() <<  "\n";

If I try to get an object that is not of the type stored in the variant, the system will throw a std::bad_variant_access exception, for example if I try to do this with the variant from the example above:

auto& the_student = get<teacher>(the_variant);

To execute a specific method of a given class, I do not need to do any downcasting because I already have the object of the given type, so, instead of:

static_cast<crew&>(*people.find(32)->second).help_team();

I would do:

get<crew>(people.find(32)->second).help_team();

that is by far straight and cleaner.

Now, given I have a method called “do_something” in all my classes, I would want to be able to invoke it no matter the type of the object stored in the variant.

So, I need to do something like this in the polymorphic world:

for (auto& p : people)
{
	p.second->do_something();
}

To do this, there is a function called: std::visit.

What visit does is accessing the variant object and invoke the method passed as argument with the object stored in the variant. So, given my example, I could do something like:

auto& the_variant = people.find(14)->second;
visit([](auto& s)
{
	s.do_something();
}, the_variant);

The magic is in the “auto” part here. When you “visit” a variant, the compiler generates one method for each type specified in the variant declaration, in my case 3 (one for student, one for crew and one for teacher), and executes the specific method depending on the type of the value stored in the variant. So, to execute do_something() for all objects in the variant, I need to do something like:

for (auto& p : people)
{
    visit([](auto& s)
	{
	    s.do_something();
    }, p.second);
}

It is beautiful, isn’t it? Polymorphic-like behavior with no overhead that polymorphism brings.

C++: “auto” return type deduction

Before C++14, when implementing a function template you did not know the return type of your functions, you had to do something like this:

template <typename A, typename B>
auto do_something(const A& a, const B& b) -> decltype(a.do_something(b))
{
  return a.do_something(b);
}

You had to use “decltype” in order to say the compiler: “The return type of this method is the return type of method do_something of object a”. The “auto” keyword used to say the compiler: “The return type of this function is declared at the end”.

Since C++14, you can do something by far simpler:

template <typename A, typename B>
auto do_something(const A& a, const B& b)
{
  return a.do_something(b);
}

In C++14, the compiler deduces the return type of the methods that have “auto” as return type.

Restrictions:

All returned values must be of the same type. My example below does not compile because I am returning an “int” or a “double”.

auto f(int n)
{
	if (n == 1)
		return 1;

	return 2.0;
}

For recursive functions, a return value must be returned before the recursive call in order to let the compiler to know what will be the type of the value to return, as in this example:

auto accumulator(int n)
{
	if (n == 0)
		return 0;

	return n + accumulator(n - 1);
}

C++: Smart pointers, part 5: weak_ptr

This is the last of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

In modern C++ applications (C++11 and later), you can replace almost all your naked pointers to shared_ptr and unique_ptr in order to have automatic resource administration in a deterministic way so you will not need (almost, again) to release the memory manually.

The “almost” means that there is one scenario where the smart pointers, specifically, the shared_ptr instances, will not work: When you have circular references. In this scenario, since every shared_ptr is pointing to the other one, the memory will never be released.

Continue reading “C++: Smart pointers, part 5: weak_ptr”

C++11: Perfect forwarding

Consider this function template invoke that invokes the function/functor/lambda expression passed as argument passing it the two extra arguments given:

#include <iostream>
#include <string>

using namespace std;

void sum(int a, int b)
{
    cout << a + b << endl;
}

void concat(const string& a, const string& b)
{
    cout << a + b << endl;
}

template <typename PROC, typename A, typename B>
void invoke(PROC p, const A& a, const B& b)
{
    p(a, b);
}

int main()
{
    invoke(sum, 10, 20);
    invoke(concat, "Hello ", "world");
    return 0;
}

Nice, it works as expected and the result is:

30
Hello world

Continue reading “C++11: Perfect forwarding”

C++: Smart pointers, part 4: shared_ptr

This is the fourth post of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

As I mentioned in other posts, C++11 brings a new set of smart pointers into C++. The most useful smart pointer is shared_ptr: Its memory management policy consists in counting the number of shared_ptr instances that refer to the same object in the heap.

Continue reading “C++: Smart pointers, part 4: shared_ptr”

C++: Smart pointers, part 3: More on unique_ptr

This is the third post of several posts I wrote related to smart pointers:

  1. Smart pointers
  2. unique_ptr
  3. More on unique_ptr
  4. shared_ptr
  5. weak_ptr

Ok, here I am going to write about two other features that unique_ptr has that I did not mention in my last post.

unique_ptr default behavior consists on take ownership of a pointer created with new and that would normally be released with delete.

Continue reading “C++: Smart pointers, part 3: More on unique_ptr”

C++11: std::future and std::async

C++11 introduces support for asynchronous calls in a very easy way.

An asynchronous call is a method invocation that will be executed in a separate thread (or core or processor); so, the caller of the method does not wait for the result of the execution and continue doing what is next; in this way, the compiler/processor/operating system can optimise the execution of the program and execute several routines at the same time (given the now common multicore systems we all have at home and in our pockets!). The standard library provides the mechanisms to perform those asynchronous calls and store the results until the caller will actually need them.

Continue reading “C++11: std::future and std::async”

C++11: std::thread

The standard library that ships with the new C++11 contains a set of classes to use threads. Before this, we needed to use the OS specific thread facilities each OS provides making our programs hard to port to other platforms.

Anyway, as today (November 16th, 2012), I tried threads using g++ 4.7 in Linux, Windows (through mingw), Mac and NetBSD and I just had success in Linux, Windows and Mac do not implement the thread features and NetBSD misses some details on the implementation (the this_thread::sleep_for() method, for example). Microsoft Visual Studio 2012 ships with good thread support.

To define a thread, we need to use the template class std::thread and we need to pass it a function pointer, a lambda expression or a functor. Look at this example:

Continue reading “C++11: std::thread”

C++11: enable_if

std::enable_if is another feature taken from the Boost C++ library that now ships with every C++11 compliant compiler.

As its name says, the template struct enable_if, enables a function only if a condition (passed as a type trait) is true; otherwise, the function is undefined. In this way, you can declare several “overloads” of a method and enable or disable them depending on some requirements you need. The nice part of this is that the disabled functions will not be part of your binary code because the compiler simply will ignore them.

Continue reading “C++11: enable_if”

C++11: unordered maps

The STL ships with a sorted map template class that is commonly implemented as a balanced binary tree.

The good thing on this is the fast search average time ( O(log2N) if implemented as a balanced binary tree, where N is the number of elements added into the map) and that when the map is iterated, the elements are retrieved following an established order.

C++11 introduces an unordered map implemented as a hash table. The good thing on this is the constant access time for each element ( O(1) ) but the bad things are that the elements are not retrieved in order and the memory print of the whole container can (I am just speculating here) be greater that the map’s one.

Continue reading “C++11: unordered maps”