Auto Type Deduction
The auto keyword allows one to use C++11’s in-built type deduction.
std::string something = somethingthatreturnsastring.getString();
auto something = somethingthatreturnsastring.getString();
Auto automatically deduces that the required variable needs to be a string, and will fill in the blanks for you in place of the auto keyword. This is especially useful for iterators.
for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
it->something();
}
can be now
for(auto it = x.begin(); it != x.end(); i++)
{
it->something();
}
Wow! Cleaner code!
Strongly Typed Enums
This is useful for preventing enum name collisions, a potential source of bugs. In the older C++, one had to specify enums that were unique throughout the program. Previously, if you used None as a enum value, no other enum group could use None. But now you can!
enum class myEnum {None, One, All}; myEnum o = myEnum ::All; auto p = myEnum::All; // also works fine
Lambdas
Lambdas are basicallly in-place functions. It is especially useful in iterators and for-loops, where it may be that you only need to use this “function” once only in the whole program, so there isn’t any point defining that function. You can’t actually accomplish something you couldn’t before with lambdas, it’s more of a convenience feature influenced by functional programming. A bare-bone one looks like this:
[]() { }
With all possible lambda operators.
[]() mutable -> T { }
Where [] is the capture list, () the argument list and {} the function body.
Capture List
The capture list defines what from the outside of the lambda should be available inside the function body and how. It can be either:
- a value: [x]
- a reference [&x]
- any variable currently in scope by reference [&]
- same as 3, but by value [=]
You can mix any of the above in a comma separated list [x, &y]
.
Argument List
The argument list is the same as in any other C++ function.
Function Body
The code that will be executed when the lambda is actually called.
Return Type Deduction
If a lambda has only one return statement, the return type can be omitted and has the implicit type of decltype(return_statement)
.
Mutable
If a lambda is marked mutable (e.g. []() mutable { }
) it is allowed to mutate the values that have been captured by value.
Here’s an example of it in action.
int main() { char s[]="Hello World!"; int Uppercase = 0; //modified by the lambda for_each(s, s+sizeof(s), [&Uppercase] (char c) { if (isupper(c)) Uppercase++; }); cout<< Uppercase<<" uppercase letters in: "<< s<<endl; }
Unique Pointers
Unique pointers are a class of smart pointers in C++11.
When you define an object using an unique_ptr, the object is destroyed and its memory deallocated when either of the following happens:
– unique_ptr managing the object is destroyed
– unique_ptr managing the object is assigned another pointer via operator= or reset().
For the layman though, it means that when you declare an object using the unique pointer idiom, you do not have to manually delete the object before it goes out of scope.
Previously, one would do this:
YourObject * obj = new YourObject();
and at the end of it all you would have to be sure to
delete(obj);
else you would have a memory leak.
Now,
std::unique_ptr<YourObject> obj(new YourObject());
When obj goes out of scope, the memory is free-ed for you.
static_assert
static_assert is basically asserts that are executed during compile time. For example, you can do the following:
static_assert(sizeof(unsigned int) * CHAR_BIT == 32);
If for some reason the comparison above is not valid for your system, the static_assert would fail.
Another way it can be used is to use it with C++ type traits. For example,
static_assert(std::is_pod<yourstruct>::value, "Not a pod struct!");
POD stands for Plain Old Data – that is, a class (whether defined with the keyword struct
or the keyword class
) without constructors, destructors and virtual members functions. So basically, if a silly new programmer comes along and decides to add a constructor to a particular struct or class, this static_assert will prevent compilation and single out this error. Useful for maintenance of code!
There are lots more in C++11 that are useful. As I discover more, I’ll post them, maybe in a part 2. Thanks for reading.
C# getting better and better. Really like first class functions, feel that a language is incomplete without it.
LikeLike
The thing about c#, it’s still not as “close to the metal” as c++ , in c++ you can use c as well. Almost every linux machine you can find gcc and g++, so that’s a big win. I like c# as well though, it’s a nice language.
LikeLiked by 1 person
I tried to compile your mutable example, it does not seem to work. “/home/emangel/Dev/Projets/Dicom_Test/sans_titre/main.cpp:19: erreur : no matching function for call to ‘for_each(char [13], char*, main()::__lambda0)’
});”
Did I forget an include?
LikeLike
It compiles fine here. Are you using C++11? You have to add -std=c++11 to your compiler/linker. (assuming u r using g++)
LikeLiked by 1 person
I do have a warning about that, but I think it should be OK since it says it’s enabled by default.
“/home/emangel/Dev/Projets/Dicom_Test/sans_titre/main.cpp:19: avertissement : lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]
});
^”
LikeLike
I had to add
#include
using namespace std;
Full code:
#include
using namespace std;
int main()
{
char s[]=”Hello World!”;
int Uppercase = 0; //modified by the lambda
for_each(s, s+sizeof(s), [&Uppercase] (char c) {
if (isupper(c))
Uppercase++;
});
cout<< Uppercase<<" uppercase letters in: "<< s<<endl;
}
LikeLiked by 1 person
[…] 5 Useful Things in C++11 // Lobsters […]
LikeLike
[…] Kernel Panic: 5 корисних речей в C++11. […]
LikeLike