Don wrote:I have been considering migrating Komodo to C++, but just sticking my big toe in the water - avoiding most of the features. I wrote a chess program in c++ but it was essentially just a c program compiled with c++.
But I am attracted to C++ for the templates and to c++11 or whatever they are calling it these days for the new features and my belief that they fix some of the warts in the language and make it less likely I will shoot myself in the foot with it.
Has anyone here ventured into that?
I have been migrating to C++11 as the features come available within Visual C++, and it really shortens code. But my draughts engine already was a template heavy C++ program. Because you only use the C subset of C++ (I know it's not a proper subset, but roughly speaking it is), I won't talk much about the OO side of C++ or the resource management safety that comes with the new smart pointers. But you still might need to slighly modify your programming style to get the greatest benefit of all the other new features.
First, it is really convenient to be able to declare variables in local scope. So in C++ you don't declare a bunch of variables at the top of a function, but instead only at their first point of use. (NOTE: this point is not followed by Stockfish, sometimes for good reason, but mostly I think it could be improved) E.g.
Code: Select all
for (int i = 0; i < N; ++i) {
// bla, local i
}
for (int i = 0; i < N; ++i) {
// more bla, different local i!
}
Second, if you also get into the habit of initializing variables on first use, you can use the new C++11 auto keyword
Code: Select all
for (auto i = 0; i < N; ++i) {
// bla, i has type int
}
For int this won't give you much, but as soon as you are doing stuff with the STL, and start looping over iterators, it will be really good. I use auto everywhere.
Third, the ability to use lambdas in combination with the STL is a big boost. So instead e.g. the old C-style qsort with a function pointer to a cmp() function, in C++ you would pass a function object (a struct with a function operator())
Code: Select all
struct comp
{
bool operator()(Move const& lhs, Move const& rhs) { return lhs.score() < rhs.score(); };
};
// some std::vector moves already initialized
std::sort(moves.begin(), moves.end(), comp()); // comp can be inlined!
The advantage is that the function object gets inlined (which qsort cannot do because it is already compiled) during compilation of the std::sort header. Still, you have to manually write a function object.
Now in C++11 you can define a lambda (basically the function equivalent of a temporary expression) within the sort call and let the compiler generate the function object
Code: Select all
std::sort(moves.begin(), moves.end(), [](Move const& lhs, Move const& rhs) {
return lhs.score() < rhs.score();
});
A final big improvement with C++11 is the use of move semantics, where much of the copying around of temporary stuff that the old C++ used to do has been eliminated. With both Visual C++ and gcc 4.7 this has been implemented in all the STL containers and algorithms.
There is tons of information available, e.g. this great presentation
http://channel9.msdn.com/Events/GoingNa ... and-Beyond by Herb Sutter should give you a much more thorough overview.