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;
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:
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)). BLOCKQUOTE <>
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.