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.