Summary: We are considering adopting new cleaner & more flexible C++ language features. This may not work with some older compiler versions. Opinions are warmly welcomed! -----
Hi All,
At the Hackfest, we discussed adopting features from the C++11 standard into our code. The advantages are (among others) significantly cleaner, more flexible and more readable syntax. I've included three examples at the end of this message.
Our discussion included consideration of users of older compilers. A convenient summary of compiler support is available at [1]. Several features (illustrated in the examples below) are well supported, including range-based for loops, type inference and variadic templates.
If we adopt these three specific features, we will require:
GCC >= 4.6 Clang >= 3.1 (or another suitable compiler!)
A complete migration to C++11 would require:
GCC >= 4.8.1 Clang >= 3.3
I propose that we adopt C++11 on a feature-by-feature basis, with discussion before requiring any bump in compiler version. We can track this in the wiki or similar.
We could potentially consider introducing a couple of the "safer" features within the next release cycle. Maybe even in time for 0.92?!
I will be pushing some demos of C++11 features to the branch lp:inkscape/~valavanisalex/inkscape/cpp11-port [2] for testing by other devs/testers before we consider merging anything into trunk. I will let you know when anything interesting is there!
We're very interested in any opinions or comments! Will this migration affect you? Is it good for the project? Do you see any trouble ahead?
Best wishes,
Alex
[1] http://en.cppreference.com/w/cpp/compiler_support [2] https://code.launchpad.net/~valavanisalex/inkscape/cpp11-port
(Examples follow)
== 1. Type inference ==
The compiler can automatically determine the type of variables, based on the return type of functions etc. For example:
std::vector<std::pair<Glib::ustring, Glib::ustring> > pairs = ColorProfile::getProfileFilesWithNames();
becomes...
auto pairs = ColorProfile::getProfileFilesWithNames();
== 2. Range-based for-loops ==
Often, we just want to iterate over the entire contents of a container. The syntax is much cleaner in C++11:
for(std::vectorInkscape::SnapCandidatePoint::iterator i = _all_snap_sources_sorted.begin(); i != _all_snap_sources_sorted.end(); ++i){ // whatever }
becomes...
for(auto &i : _all_snap_sources_sorted){ // whatever }
== 3. Variadic templates ==
Sometimes we want many variants on the same function that take a different number of arguments. For example:
template <typename CurveType, typename A> void appendNew(A a) { // whatever }
template <typename CurveType, typename A, typename B> void appendNew(A a, B b) { // whatever }
<snip />
template <typename CurveType, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> void appendNew(A a, B b, C c, D d, E e, F f, G g, H h, I i) { // whatever }
This long (and incomplete) set of functions can be replaced by a single variadic template in C++11:
template <typename CurveType, typename... Args> void appendNew(Args... args) { // whatever }