pre-increment and post-increment in C++

Maybe you have wondered why there are 2 types if increment operators in C++ and why it matters in some situations.

Lets have a variable i of type int. Pre-increment would be ++i, and post-increment is i++ as we learned it in school;

The result in both ways is the same, it increments the variable i by 1. The difference is how it behaves when passing i along to a function:

void doSomething(int i) {
  std::cout << i << std::endl;
}

int i = 12;
doSomething(i++); // prints 12
// i is now 13
int i = 12;
doSomething(++i); // prints 13
// i is now 13

The explanation

Pre-increment increments the value of i and returns a reference to the now increased i.

Post-increment makes a copy of i, then increments i, but returns the copy.

std::map and the 2 evils

The task: store pairs of keys and objects in a map. Sounds simple? Well. std::map offers several ways of accessing its members:

operator[key]
at(key)
find(key)

That all sounds good as long as the key exists in the map. If not, it can get tricky: the operator[] inserts the key and a default constructed element, which often might be undesired, and we also cannot use it with const.

And the at() method? Throws an exception. There is a chance you don’t want neither of them.

What we still can try is getting an iterator using find():

auto it = myMap.find(9);

The iterator needs to be checked to not be end(), in case the element doesn’t exist in the map.

The value type of a map is std::pair<const Key, T>, so we can get the key and element from the iterator like so:

auto key = it->first;
auto value = it->second;

async unit tests in C++

Sometimes we are in the situation where we need to test the result of a callback that is invoked on another thread and we don’t know when this will happen.

The problem? Our test already runs out of scope before the callback gets called. In order to test such a scenario we’ll need the following:

Lets assume we have a downloader that takes a while to download something, and (hopefully) reports true when it was successful:

class Downloader {
    asyncDownload(std::string url, std::function<void(bool)> callback) {
        std::thread downloadThread(download, std::move(callback));
        downloadThread.join();
    }

    download(std::string url, std::function<void(bool)> callback) {

        // perform download which takes a while
        ...
        if (everythingWentWell)
            callback(true);
    }
};

We could start writing our test case like this:

TEST(Downloader, testDownload) {
    auto callback = [](bool success) {
        EXPECT_TRUE(success);
    };
    Downloader downloader;
    downloader.download("http://foo.bar/interesting-file.jpg", std::move(callback));
}

This will leave us in a situation where the test case finishes while the Downloader is still downloading. What we need now is a way for the test case to wait until the callback is invoked, with a maximum timeout.

The way to go here is a promise with a 30s max timeout:

std::promise<void> waitGuard;
...
    EXPECT_EQ(boost::future_status::ready, waitGuard.get_future().wait_for(std::chrono::seconds(30)));

When the callback gets invoked, we inform the wait guard by setting a value. The test case now looks like this:

TEST(Downloader, testDownload) {
    std::promise<void> waitGuard;
    auto callback = [&](bool success) {
        // remember this gets called on the other thread
        EXPECT_TRUE(success);
        waitGuard.set_value();
    };
    Downloader downloader;
    downloader.download("http://foo.bar/interesting-file.jpg", std::move(callback));
    EXPECT_EQ(boost::future_status::ready, waitGuard.get_future().wait_for(std::chrono::seconds(30)));
}

Now, the test will wait until the download finishes and the callback gets called, but not more than 30s.