Sunday, May 27, 2012

C++11 Delegating Constructors.

Another much needed improvement to c++ is the problem of code reuse in constructors. Often you where forced to create an "init" function and call that from the body of the constructor. What this means is that you are effectively default constructing the member variables of the object and then re-initializing them to setup them uin p the common "init" function.

The new standard fixes this by allowing Delegating Constructors. Basically one constructor can now call another one from the same class in its place.

Heres an example:
//compile with  g++ -std=c++11 $< -o $@
#include <iostream>

class DelgateConstructor
{
  std::string str_;

public:
  DelgateConstructor(char* s) : 
    str_(s)
  {
    std::cout << "Working...\n";
  } 

  DelgateConstructor() :
    DelgateConstructor("Here we are") 
  {
    std::cout << str_ << "\n";
  }
};

int main()
{
  DelgateConstructor whatever;
}
This results in this output:
Working...
Here we are

Saturday, May 5, 2012

fixing a lost ubuntu unity dash

Gahh... blue screen of death was a blessing.. unix systems really can get themselves in all kinds of crazy twists. I have been trying out that various media center software for ubuntu lately... Its bad worst and just plain ugly.. Mythtv, freevo ... nothing just works nicely they have trouble doing the basic of playing an avi from a hard disk, or booting up with out destroying the monitor settings if the TV is powered down... out of all of it the one that works the best is vlc... surprise surprise.. Im on the vague of setting up a web server hacking some php together that talks to a telnet interfaced vlc deamon that boots up at start up... and calling it a day...

Anyway back to the point.. playing with this stuff tends to brick your box real quick. basically the lot of them are too invasive and over bloated with addtional power features while neglecting the basics... On several of my trials i lost the unity dash and menu-bars here is how i was restoring it.

Punch ctrl+alt+f1 if you cant get a terminal(might be safer to do it here anyway) then run
unity --reset
sudo restart lightdm
Punch ctrl+alt+f7 to jump back to the GUI interface and watch/check the restart..

May take 1 or 2 tries and its a little slow and sometimes get stuck doing the --reset.

Friday, May 4, 2012

c++11 lambda

c++11 lambdas

Lambdas are an excellent and long awaited addition to the c++ language. Lambdas where simply not possible before but the Boost lib offered a rather passable set of macros that let you get away in-lining a kin of lambda. (basically it was a series of functional objects)

The lambda syntax however makes my skin itch a bit. It is yea another reuse of the bracket characters - [](){} - and one that is potentially lowering the readability of the code and introducing coding errors as a result. I would have preferred something a bit more clear and obvious.

Firstly the basic lambda syntax is [capture](parameters)->return-type {body}. This is often short handed the most basic form when people blog and type about it which is []() { .... }


The first [] pair forms a "capture". The capture is run one time at and in the context of the lambdas creation(ie the point where you put the code). There several convenient shortcuts that grab the various variables from the current context automatically. Consider these to be members (and constructor params) of the resulting lambda object.

The next () pair forms the "parameters" these are the same as the parameters of a function definition. This resembles the operator(...) function call of a functional object or the parameter list of a function pointer. Note that these ARE surprisingly optional, but generally they are not left out.

The difference between capture and parameters is rather subtle (or obvious depending on your point of view or experience with it to date). It can at can seem like overkill or just outright fluff when you are constantly using lambdas in the local context. However the key point to realize is that if you pass the resulting lambda out of the current context without executing it then the "capture" has already completed for the context that you made it in and passed it out of. As a result the parameters in the capture must still be IN CONTEXT at the point of the Lambdas actual execution (or the capture was made by value). Parameters on the other hand are filled in when the Lambda is actually executed.

The -> forms the return type. It is optional and often left out. However it can become quite important when templates are used with lambdas otherwise the compiler can get terribly confused with which of the specializations are supposed to be put in place. I assume this is just be a problem with the maturity level of the current gen of c++11 compilers.

And of course the {} forms the body of the code. The same scoping rules apply here as if you coded the object as a completely separate member function of a functional object. So keep in mind that you can not reach outside to variables that where not passed in through the capture or params.

Ok an example: The little known summing of numbers.. zzZZZ.. ha wadaimiss...


// comile with 
//  g++  -std=c++11 lambda.cpp

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

void examplePassByValue(int* start, int* end)
{
  int stuff[]={1,2,3,4,5,6,7,8,9};
  int sum = 0; 
  std::for_each(stuff, stuff+(sizeof(stuff)/sizeof(int)), [sum] (int v) 
    {
      std::cout << v << "\n";
    // This is passed by const value (os its BAD.. if you try to modify it.. )
    //sum += v;
    });
}

void examplePassByRef(int* start, int* end)
{
  int sum = 0; 
  std::for_each(start, end, [&sum] (int v )
  {
    std::cout << v << "\n";
    sum += v;
  });
  std::cout << " sum is : "<< sum << "\n";
}

void examplePassByRefImplicatScoped(int* start, int* end)
{
  return;

  // pass by ref of the entire implicat scope
  int sum = 0; 

  std::for_each(start, end, [&] (int v) 
  {
    std::cout << v << "\n";
    sum += v;
  });
  std::cout << " sum is : "<< sum << "\n";
}

// and now the fun...
template <class T>
void filterTo(T* start,
       T* end,
       std::function<bool (const T&)> filter,
       std::function<void (const T&)> action
       )
{ 
  std::for_each(start, end, [=] (T v) { if ( filter( v ) ) action( v ); });
}

void exampleStdFunctionLambdaNoClosure(int* start, int* end)
{
  //lambda compiling to a function pointer compatible with std:function
  std::function<bool (const int&)> filter
    = [](const int& v)->bool { return v%2; };
  std::function<void (const int&)> action
    = [](const int& v)->void { std::cout << "filt odd: " << v << "\n"; };

  filterTo(start, end,
    filter, action);
}

void exampleLambdaNoFunctionTemplateWeakness(int* start, int* end)
{
//  //This is the same as above and should work however the curent 
//  // compiler is  very poor at solving this.. so it dies
//  filterTo(start, end,
//    [](const int& v)->bool { return v%1; },
//    [](const int& v)->void { std::cout << v << "\n"; });
}

void exampleStdFunctionLambdaClosure(int* start, int* end)
{
  //evil: lambda closure is creates a class object not a function pointer
  // this can still wrap up in the std::function 
  int sum = 0;
  std::function<bool (const int&)> filter
    = [](const int& v)->bool { return v%2; };
  std::function<void (const int&)> action
    = [&sum](const int& v)->void {  sum += v; std::cout << "run sum:" << sum << "\n"; };

  //lambda compiling to a function pointer compatible with std:function
  filterTo(start, end,
    filter, action);

  std::cout << "Tot sum:" << sum << std::endl;
}

int main()
{
  int stuff[]={1,2,3,4,5,6,7,8,9};
  int* end = stuff + (sizeof(stuff)/sizeof(int)); //warning this is pointer arithmetic
 
  //suming examples
  examplePassByValue(stuff, end);
  examplePassByRef(stuff, end);
  examplePassByRefImplicatScoped(stuff, end);

  //find all odds..
  exampleStdFunctionLambdaNoClosure(stuff, end);
  exampleStdFunctionLambdaClosure(stuff, end);
  
  return 0;
}

Since this is a bit of a mess to run here is the make to build and run it (set BASE) to match your mingw 4.7 install path
BASE=/c/tools/mingw47
export PATH:=${BASE}/i686-w64-mingw32/lib:${BASE}/bin:${PATH}

all: run

lambda.exe: lambda.cpp
 g++ -std=c++11 lambda.cpp -o lambda.exe

run: lambda.exe
 lambda.exe



Refer: http://www.cprogramming.com/c++11/c++11-lambda-closures.html