LINQ for C++ with cpplinq

4. April 2014

 

When it comes to programming languages, I literally use dozens, but when it comes down to an all other things being equal decision my go to language of choice tends to be C#.  One of the big plus sides of C# is the wonderful LINQ ( Language Integrated Query ).  LINQ makes heavy use of lambda (closures) a feature lacking until recently in C++.  Now with lambda expressions part of the C++ language LINQ for C++ is now a possibility.  It exists as a single hpp file you add to your project.

 

If you aren’t already familiar with LINQ, here is a simple example in C#.  It’s a simple scoreboard that sorts the results by name, then by score, then totals and averages all of the scores.  As you can see, it’s a very compact and clean way to access data.

 

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication1
{
class Entry{
public Entry(string name, int score)
{
this.name = name;this.score = score;
}
public string name { get; set; }
public int score { get; set; }
}
class Program{
static void Main(string[] args)
{
List<Entry> scoreEntries = new List<Entry>();
scoreEntries.Add(new Entry("mike", 42));
scoreEntries.Add(new Entry("bob", 99));
scoreEntries.Add(new Entry("doug", 99));
scoreEntries.Add(new Entry("steve", 12));var sortedByName = scoreEntries.OrderBy(item => item.name).ToList();Console.WriteLine("Sorted by score");
sortedByName.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });Console.WriteLine("\nSorted by name");var sortedByScore = scoreEntries.OrderBy(item => item.score).ToList();
sortedByScore.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });var totalOfScores = scoreEntries.Where(item => item.score > 0)
.Sum(item => item.score);var averageScore = scoreEntries.Average(item => item.score);Console.WriteLine("\nTotal of scores == " + totalOfScores + " Average Score == " + averageScore);
}
}
}

 

Now let's take a look at the C++ version using cpplinq:

#include <string>#include <list>#include "cpplinq.hpp"#include <iostream>class Entry{
public:Entry::Entry(std::string name, int score){
this->name = name;this->score = score;
}
std::string name;int score;
};int main(int argc, char **argv)
{
std::list<Entry> scoreEntries;scoreEntries.push_back(Entry("mike", 42));scoreEntries.push_back(Entry("bob", 99));scoreEntries.push_back(Entry("doug", 99));scoreEntries.push_back(Entry("steve", 12));using namespace cpplinq;auto sortedByName = from(scoreEntries)
>> orderby_ascending([](const Entry & entry){ return entry.name;  })
>> to_vector();auto sortedByScore = from(scoreEntries)
>> orderby_descending([](const Entry & entry){ return entry.score;  })
>> to_vector();std::cout << "Sorted by name" << std::endl;from(sortedByName)
>> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });std::cout << std::endl << "Sorted by score" << std::endl;from(sortedByScore)
>> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });auto totalOfScores = from(scoreEntries)
>> select([](const Entry & entry){ return entry.score; })
>> sum();auto averageScore = from(scoreEntries)
>> select([](const Entry & entry){ return entry.score; })
>> avg();std::cout << std::endl << "Total of scores == " << totalOfScores << " average score == " << averageScore << std::endl;return 0;
}

 

A few obvious differences.  Cpplinq statements start with the from methods defining the type of data source to perform on.  In this case I used the default from() which takes a standard C++ STL type.  There are also from__array() and from_range() for working with arrays and iterators respectively.  Next the . (dot) operator has been replaced with the >> operator.  Of course the lambda syntax is different as well ( C++’s is much uglier ), otherwise at the end of the day, it is very similar to LINQ in both look and execution.

 

If you are new to C++ and are struggling to wrap your head around the uses for lambdas, give cpplinq a shot and you will quickly see their value!

Programming








blog comments powered by Disqus

Month List

DisqusCommentsSummary