- #1
Grep
- 298
- 3
The Final Draft of the standard for the next version of C++ (referred to as C++0x) was just completed, it seems. There are other things to do before it's official and completed, but it's a big milestone. So I was curious what was available in the GCC compiler from the new spec. There's a list here:
http://gcc.gnu.org/projects/cxx0x.html
Quite a bit, really, in fact. Some useful stuff was available with version 4.4 of gcc, which I had installed on my Linux system. But I soon wanted to see some of the features in the new 4.6 version, so I compiled that. So far, so good.
I thought it might be interesting for others if I show you some of the features that I like the best so far. But really, initialization lists and ranged for loops would be enough to get me excited. Anyways, this gives you a chance to take a peek at the new features and see an example of how they work. If that doesn't interest you, read no further.
I installed gcc-4.6.0 in my home directory so I don't mess anything up, and I'll briefly go over how I get my test program to compile and run. It's a super simple setup, so don't expect much. I have one source file called Main.cpp which I compile with this (putting your home directory where I marked, and making sure the CC variable is your compiler binary):
I also ran these two lines in the shell before running the program:
To get someone up and running quickly, this is the main part of the test program in Main.cpp:
Now I'll just go through the explanatory test functions one by one. To run each function, just call it from the previous program's main function.
Possibly my second favorite new feature is the initializer list. A long time in coming. It's so far been annoying to initialize a vector or similar container with a static list of values. You end up either making an array initialized properly, and using it to construct a vector, or you use push_back() or similar on each element. Yuck.
Not any more! Behold!
I would also draw your attention to the way I accessed the variables in the pair. Normally, we'd have to use it->first and it->second. That get is also usable in the new tuples, which I'll get to later.
Also note that max() now accepts initializer lists as well. I'll get to 'auto' soon.
Which leads into my current favorite new feature: Ranged for. Wow, how I miss it when I use C++. It was one of the nicer new features in java when it was introduced. The normal way of using iterators is a bit verbose and unnecessary, I think.
This, on the other hand, I like:
Also really handy is the new auto type. Auto works like this:
Though I'll probably used ranged for more than iterators now, auto can clean up an iterator. Look at the one I used to go through the 'languages' list in testInitializerLists(), above. It can be written:
Somehow I get the feeling auto may be abused, though, but that's C++ for ya.
Enum classes are also of interest:
I do like the way the actual underlying type of the enum can be specified, and the scoping (i.e. It's not 'red' it's 'Color::red').
And then there's the tuples, which are sure to come in handy:
Also in my list of top new features is Lambda. Let's say you're trying to sort a vector, but you want to use your own comparator. Annoying, right? Easy now:
See how easy it was to define a new comparator to make it sort by absolute value? A vast improvement, in my opinion. Doing that previously just seemed to be more difficult than it should have been.
We also have a new array type, for fixed-size arrays:
They've also added new time functionality. Of course, there's always the Boost libraries, but these will come in handy:
For the last feature, it's one I've always missed, and it's a simple one. They added 'nullptr' to represent a null pointer value. I know right? Earth. Shattering.
Well, that's where I'm at so far. There's plenty more features, but that's plenty for one post. Hope that was actually interesting to someone here! I'm sure many of you use C++, and that's going to be the standard soon enough.
I should mention that snippets were taken from Bjarne Stroustrup's FAQ on C++0x at:
http://www2.research.att.com/~bs/C++0xFAQ.html
http://gcc.gnu.org/projects/cxx0x.html
Quite a bit, really, in fact. Some useful stuff was available with version 4.4 of gcc, which I had installed on my Linux system. But I soon wanted to see some of the features in the new 4.6 version, so I compiled that. So far, so good.
I thought it might be interesting for others if I show you some of the features that I like the best so far. But really, initialization lists and ranged for loops would be enough to get me excited. Anyways, this gives you a chance to take a peek at the new features and see an example of how they work. If that doesn't interest you, read no further.
I installed gcc-4.6.0 in my home directory so I don't mess anything up, and I'll briefly go over how I get my test program to compile and run. It's a super simple setup, so don't expect much. I have one source file called Main.cpp which I compile with this (putting your home directory where I marked, and making sure the CC variable is your compiler binary):
Code:
GCC_HOME=${HOME}/gcc-4.6.0
PATH := ${GCC_HOME}/bin:${PATH}
LD_LIBRARY_PATH := ${GCC_HOME}/lib
LD_RUN_PATH := ${LD_LIBRARY_PATH}
CC=g++-4.6
CFLAGS=-std=c++0x
all:
${CC} ${CFLAGS} Main.cpp -o Main
I also ran these two lines in the shell before running the program:
Code:
export PATH=${PATH}:$HOME/gcc-4.6.0/bin
export LD_LIBRARY_PATH=$HOME/gcc-4.6.0/lib
To get someone up and running quickly, this is the main part of the test program in Main.cpp:
Code:
#include <iostream>
#include <vector>
#include <list>
#include <array>
#include <tuple>
#include <algorithm>
#include <chrono>
#include <ratio>
using namespace std;
void testAuto();
void testRangeFor();
void testEnumClasses();
void testInitializerLists();
void initListFunc(initializer_list<int> list);
void arrayTest();
void testTuple();
void testTime();
void testLambda();
void testNullptr();int main(int argc, char *argv[])
{
// Add calls to test functions here
return 0;
}
Now I'll just go through the explanatory test functions one by one. To run each function, just call it from the previous program's main function.
Possibly my second favorite new feature is the initializer list. A long time in coming. It's so far been annoying to initialize a vector or similar container with a static list of values. You end up either making an array initialized properly, and using it to construct a vector, or you use push_back() or similar on each element. Yuck.
Not any more! Behold!
Code:
void testInitializerLists()
{
vector<double> v = { 1, 2, 3.456, 99.99 };
cout << "--- Initializer Lists ---\n";
cout << "v[1] = " << v[1] << '\n';
cout << "Max of {1, 5, 10, 6, 3} = " << max({1, 5, 10, 6, 3}) << '\n';
list<pair<string,string>> languages = {
{"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
};
list<pair<string,string>>::iterator it;
for (it = languages.begin(); it != languages.end(); it++)
{
// OOOOOOH, a cleaner way to access pair/tuple types, nice...
cout << get<0>(*it) << " -> " << get<1>(*it) << endl;
}
initListFunc({1, 2, 3, 5, 6 , 7, 9});
}
void initListFunc(initializer_list<int> s)
{
for (auto p = s.begin(); p != s.end(); ++p)
{
cout << *p << '\n';
}
}
Also note that max() now accepts initializer lists as well. I'll get to 'auto' soon.
Which leads into my current favorite new feature: Ranged for. Wow, how I miss it when I use C++. It was one of the nicer new features in java when it was introduced. The normal way of using iterators is a bit verbose and unnecessary, I think.
This, on the other hand, I like:
Code:
void testRangeFor()
{
vector<int> list = {2, 42, 53, 137};
cout << "--- Range for of vector<int> ---\n";
for (int x : list)
{
cout << dec << x << '\n';
}
cout << "--- Range for of static ints ---\n";
for (auto x : {1,2,3,5,8,13,21,34 })
{
cout << dec << x << '\n';
}
}
Also really handy is the new auto type. Auto works like this:
Code:
void testAuto()
{
int a = 43;
double b = 203.3;
auto x = a * b;
cout << "--- auto type ---\n";
cout << a << " * " << b << " = " << x << std::endl;
}
Code:
for (auto it = languages.begin(); it != languages.end(); it++)
{
... etc ...
Enum classes are also of interest:
Code:
void testEnumClasses()
{
enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U };
enum class Color : unsigned long {red = 0xFF0000, green=0x00FF00,
blue=0x0000FF};
cout << "--- Enum classes ---\n";
cout << EE1 << endl;
cout << "0x" << hex << EEbig << endl;
Color col = Color::red;
cout << "Color RGB: 0x" << (unsigned long)col << endl;
switch (col) {
case Color::red:
cout << "RED" << '\n';
break;
case Color::green:
cout << "GREEN" << '\n';
break;
case Color::blue:
cout << "BLUE" << '\n';
break;
default:
break;
}
cout << dec;
}
And then there's the tuples, which are sure to come in handy:
Code:
void testTuple()
{
// t will be of type tuple<string,int,double>
auto t = make_tuple(string("Herring"),10, 1.23);
cout << "--- tuple ---\n";
string s = get<0>(t);
int x = get<1>(t);
double d = get<2>(t);
cout << "tuple<\"" << s << "\", " << x << ", " << d << ">" << endl;
}
Also in my list of top new features is Lambda. Let's say you're trying to sort a vector, but you want to use your own comparator. Annoying, right? Easy now:
Code:
void testLambda()
{
vector<int> v = {50, -10, 20, -30};
cout << "--- Lambda ---\n";
sort(v.begin(), v.end()); // the default sort
// now v should be { -30, -10, 20, 50 }
cout << "List: ";
for (auto el : v)
{
cout << " " << el;
}
cout << endl;
// sort by absolute value:
sort(v.begin(), v.end(), [](int a, int b) { return abs(a)<abs(b); });
cout << "List after sort by absolute value with lambda: ";
for (auto el : v)
{
cout << " " << el;
}
cout << endl;
}
We also have a new array type, for fixed-size arrays:
Code:
void arrayTest()
{
cout << dec << "--- Array test ---\n";
array<int,6> a = { 1, 2, 3 };
a[3]=4;
for (int i = 0; i < a.size(); i++)
{
cout << "a[" << i << "] = " << a[i] << '\n';
}
cout << "Sum: " << accumulate(a.begin(), a.end(), 0) << endl;
}
They've also added new time functionality. Of course, there's always the Boost libraries, but these will come in handy:
Code:
void testTime()
{
using namespace std::chrono;
microseconds mms(12345);
milliseconds ms(123);
seconds s(10);
minutes m(30);
hours h(34);
cout << "--- time ---\n";
auto x = hours(2) + minutes(35) + seconds(9);
cout << "Duration of 2:35:09 in seconds (should be 9309) = " << duration<double>(x).count() << endl;
cout << " Or in decimal hours: " << duration<double,ratio<3600,1>>(x).count() << " hours\n";
auto t = monotonic_clock::now();
for (int i = 0; i < 1000000; i++); // waste time
auto d = monotonic_clock::now() - t;
cout << "1,000,000 useless iterations took " << duration<double>(d).count() << " seconds\n";
}
For the last feature, it's one I've always missed, and it's a simple one. They added 'nullptr' to represent a null pointer value. I know right? Earth. Shattering.
Code:
void testNullptr()
{
cout << "--- nullptr ---\n";
int *p = nullptr;
if (p == nullptr)
{
cout << "p is a nullptr\n";
}
}
Well, that's where I'm at so far. There's plenty more features, but that's plenty for one post. Hope that was actually interesting to someone here! I'm sure many of you use C++, and that's going to be the standard soon enough.
I should mention that snippets were taken from Bjarne Stroustrup's FAQ on C++0x at:
http://www2.research.att.com/~bs/C++0xFAQ.html
Last edited: