There's a lot of buzz around about the new C++ Intellisense engine in Visual Studio 2010, so I've decided to test it myself by pushing it to the limits of C++ template metaprogramming insanity, and seeing how well it copes. After some consideration, I have picked Boost.Lambda as a good example of a fairly well-known and widely-used C++ library that uses very complicated template metaprogramming to achieve its goals - if an IDE can do code completion for that thing, then it can probably handle anything else.


The test itself was fairly simple: a short C++ program that declares a Boost lambda, applies it to arguments of various types, and tries to access the result via member-access operator. The latter triggers Intellisense, so we can see what type VS thinks the expression has. For more fun, I've made a polymorphic lambda - that is, its type depends on the type of argument that is passed to it. For the sake of simplicity, I used operator << for that purpose - it has a predefined version for integers, with the same result type; and it is also overloaded for C++ stream output, returning the destination stream. So, here's our lambda:

auto f = _1 << 2;

I'm using C++0x "auto" keyword here, since the actual type of the lambda is generated by template magic, and thus rather incomprehensible. What matters is that it should be a type providing a single-argument operator(), which should take any value that can be legally substituted in place of _1 in the expression above. Note that this means that operator() there doesn't have a definite signature - it can take any predefined or user-defined type to which operator << can be applied with integer on the left. So an int is valid, and so is std::ostream, for example but the result type will obviously vary - no doubt this is going to complicate things quite a bit for Intellisense! To determine the result type, we'll introduce a pair of overloaded functions:

string foo(int x)
{
    return string();
}

pair<int, int> foo(ostream& str)
{
    return make_pair(0, 0);
}

Now we can call our lambda, pass the result to foo(), and see what members the return type of the latter has. If we see members of std::string, then the result of lambda was an int. If we see members of std::pair, then it was an ostream:

foo(f(123)).
foo(f(cout)).

 So, here comes the moment of truth at last. I'll let the screenshots speak for themselves:

Lo and behold, it works correctly! Very impressive, and this shows just how powerful the new code completion engine is - I'm not aware of any other C++ IDE, released or in beta, that can repeat that feat.