Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Monday, April 16, 2012

A Taste of C++11

Herb Sutter has an example of what C++11 feels like. Here it is, from the video:

string flip(string s) {
   reverse(s.begin(), s.end());
   return s;
}

int main() {
   vector<future<string>> v;
   
   v.push_back(async([] { return flip(   " ,olleH"); }));
   v.push_back(async([] { return flip(" egdelwonK"); }));
   v.push_back(async([] { return flip("\n!rebmahC"); }));

   for (auto& e : v) {
      cout << e.get();
   }
}
Concurrency, futures and lambda functions... Moved objects, automatic type deductions and new for loop syntax...

A whole new language, isn't it?

Friday, March 18, 2011

New features in C++0x allow really impressive stuff...

Slack has a very interesting blog entry about Automatic memoization in C++0x...

Memoization is a pretty well-known optimization technique which consists in “remembering” (i.e.: caching) the results of previous calls to a function, so that repeated calls with the same parameters are resolved without repeating the original computation.

He starts with the short and simple Python function that returns a memoized function from any regular one, and then shows how C++0x features can be used to do the same!

Very impressive...

Wednesday, December 15, 2010

Factoring exception handling code in C++

When writing exception handlers (e.g. around calls to database or network related code), you often end up with the same set of catch clauses at each call site. Suppose you end up with the following code:

try {
  //...
} catch (std::runtime_error& e) {
  std::cout << "Runtime error: " << e.what() << std::endl;
} catch (...) {
  std::cout << "Unknown exception!" << std::endl;
}

You have this piece of code repeated dozens of times, which is not really a Good Thing(tm)... A little C++ trick can help you avoid those repetitions: (1) factor the common code into a single function or method that rethrows the active exception and catches it immediately, and (2) catch all exceptions at the call sites and call this handler!

#include <iostream>
#include <stdexcept>

void exception_handler() {
  try {
    throw; //rethrow the current exception
  } catch (std::runtime_error& e) {
    std::cout << "Runtime error: " << e.what() << std::endl;
  } catch (...) {
    std::cout << "Unknown exception!" << std::endl;
  }
}

int main() {
  try {
    throw std::runtime_error("unable to comply...");
  } catch (...) { exception_handler(); }

  try {
    throw 1;
  } catch (...) { exception_handler(); }

  return 0;
}

You must be careful to not call exception_handler() outside a catch clause: the trow statement calls terminate() if there is no active exception to rethrow!

You may wonder if one could use the std::uncaught_exception() function to protect against this.

void exception_handler() {
  try {
    if (!std::uncaught_exception()) {
      return; // Nothing to rethrow...
    }
    throw; //rethrow the current exception
  } ...
}

But this does not work: uncaught_exception() "returns true after completing evaluation of the object to be thrown until completing the initialization of the exception-declaration in the matching handler", as the standard says. And when exception_handler is entered, this is generally from the catch clause, and the exception has thus been caught... Your handler would now simply swallow all the exceptions!...

Actually, uncaught_exception is pretty much useless...

Thursday, August 26, 2010

Implementing One-to-Many Relationships in C++

The need to manage relations between objects is at the core of many business applications: objects refer to each other with various semantics, with or without inverse links, for various durations.

A very common case is the One-to-Many relation: a Owner object has relationships with several User objects. The owner must know which objects it is related to, and the users have an inverse link to their owner.  When a user is added to or removed from its owner, both links should be updated.  When the owner is destroyed, all the owned objects are also destroyed.  Such relations are extremely common, and often implemented with ad-hoc code.

This paper proposes a set of classes to implement those One-to-Many relations with a minimal amount of code to be written in the Owner and User classes, and performance equivalent to hand-written code, both in terms of memory and CPU.

Here is an example...

#include "relations.h"

#include <iostream>
#include <string>

using namespace relations;

class User;
class Owner;

class Named {
public:
  Named(const std::string& name) 
    : _name(name) {}
  const std::string& name() const {
    return _name;
  }
  ~Named() { 
    std::cout << "Object '" << _name << "' destroyed" << std::endl; 
  }
private:
  std::string _name;
};

class User 
  : public RelationUser<Owner, User>
  , public Named {
public:
  User(Owner* owner, const std::string& name)
    : RelationUser<Owner,User>(owner)
    , Named(name)
  {}
};

class Owner 
  : public RelationOwner<RelationUser<Owner, User> > {
public:
  void show();
};

void Owner::show() {
  std::cout << "Users of Owner: ";
  for (Owner::iterator it (begin()); it != end(); ++it) {
    std::cout << (*it)->name() << " ";
  }
  std::cout << std::endl;
}

void test()  {
  Owner* owner (new Owner());
  User* user1 (new User(owner, "1"));
  User* user2 (new User(owner, "2"));
  User* user3 (new User(owner, "3"));
  owner->show();

  delete user2;
  owner->show();

  delete owner; // All users deleted
}

int main() {
  test();
  return 0;
}


And the output is:

  Users of Owner: 1 2 3
  User '2' destroyed
  Users of Owner: 1 3
  User '1' destroyed
  User '3' destroyed

Enjoy...

Tuesday, October 20, 2009

ACCU -- Professionalism in programming

If you're serious into programming, you should probably be a member of ACCU.
ACCU is an organisation of programmers who care about professionalism in programming and are dedicated to raising the standard of programming.
ACCU publishes journals, runs both targeted mentored projects and a yearly conference, and hosts mailing lists to help programmers develop their skills and professionalism.
I never had the chance to go to the conference, but the journals are very interesting (Overload is publicly available online).  Here is the table of content of Overload 93:
  • The Model Student: A Primal Skyline (Part 2) -- Richard Harris continues investigating the integers’ factors.
  • Multi-threading in C++0x -- Anthony Williams introduces us to the new threading library.
  • Quality Matters: Correctness, Robustness and Reliability -- Matthew Wilson defines various measures of quality.
  • The Generation, Management and Handling of Errors (Part 2) -- Andy Longshore and Eoin Woods present more error Patterns.
The mailing lists are also a great source of wisdom.  There is a new mentored project that is starting about Patterns, with Kevlin Henney as mentor.  Should be great!...