C++0x support in VC10 (VS2010)
15 February, 2010 § 4 Comments
I’ve been using Visual Studio 2010 since the Beta 2 release and just a couple days ago installed the Release Candidate.
VC10 has support for some of the features of C++0x and I wanted to get a head start on playing with the features so that when we switch production environments at work I will be ready to start taking advantage.
While getting to know VC10 and C++0x, I’ve noticed a couple low-severity issues that I wanted to point out:
Lambda Functions
Lambda functions allow you to create an inline functor. They don’t supply any new capabilities of the language, but they cut out a lot of noise. Here is an example usage:
std::vector<int> numbers; numbers.push_back(1); numbers.push_back(2); std::for_each(numbers.begin(), numbers.end(), [](int number){ std::cout << number << std::endl; });
Pre-C++0x, you would have had to write this:
struct Functor { void operator()(int number) { std::cout << number << std::endl; } }; std::vector<int> numbers; numbers.push_back(1); numbers.push_back(2); std::for_each(numbers.begin(), numbers.end(), Functor());
The thing that I have noticed is that if you use using-declarations throughout your code, not all of them get captured from inside of the lambda. For example, this does not work:
void exampleFunction( const std::vector<int>& numbers ) { using std::cout; using std::endl; std::for_each(numbers.begin(), numbers.end(), [](int number){ cout << number << endl; });
For some reason, endl is not captured, and the VC10 compiler throws an error. However, either of these do work:
void exampleFunction2( const std::vector<int>& numbers) { std::for_each(numbers.begin(), numbers.end(), [](int number){ std::cout << number << std::endl; }); } // or using namespace std; void exampleFunction3( const std::vector<int>& numbers) { std::for_each(numbers.begin(), numbers.end(), [](int number){ cout << number << endl; }); }
Also, if the lambda-return-type-clause is not specified, then implicit type conversion warnings do not get generated:
std::deque<int> integers; std::transform(numbers.begin(), numbers.end(), std::front_inserter(integers), [](int number){ return number > 0 ? number / 2.0 : number * 2; // no warning here }); std::transform(numbers.begin(), numbers.end(), std::front_inserter(integers), [](int number) -> int { return number > 0 ? number / 2.0 : number * 2; // warning C4244: 'return' : conversion from 'double' to 'int', possible loss of data });
It doesn’t seem like the type inference is doing a great job with the compiler warning here. I would recommend explicitly specifying the lambda-return-type-clause to get full type checking by the compiler.