-
Range-based For Loop:
- We can now write for loops as such:
std::map<K, V> data; for (const std::pair<K, V>& pair : data) {} for (const auto& pair : data) {}
-
Explicit Virtual Override:
- We can now introduce a safety measure on virtual function override so that if the base prototype changes, our program will no longer compile until the override definition has been changed to match. This is a great safety measure in a growing code base.
class Base { public: virtual int Func(int arg) = 0; virtual ~Base() {} }; class Derived : public Base { public: // This will not compile until we change to: int Func(int arg) override {}. virtual void Func() override { ... } virtual ~Derived() {} };
-
Lambdas:
-
old way:
void _send() { VLOG(2) << "Finished send"; } void send() { socket.send("Hello World!").then(lambda::bind(_send)); }
-
new way:
void send() { socket.send("Hello World!").then( []() -> void { VLOG(2) << "Finished send"; }); }
-
-
Nullptr:
We can now replace all instances of 'NULL' with 'nullptr':
T* ptr = nullptr;
-
Unrestricted Unions:
We can now have non-pod types in unions. This allows us to
- Overlap storage allocation for objects that never exist simultaneously:
#include <string> struct T { enum {Str, Int, Double, Float} kind; T() : kind(Int) {} union Data { Data() : int_(5) {} ~Data() {} std::string str; int int_; double double_; float float_; } data; }; int main() { printf("size of T = [%ld] bytes\n", sizeof(T)); }
output:
size of T = [16] bytes
- Avoid the requirement of a default constructed object if it is a member of the union:
#include <vector> class Obj { Obj(int _arg) : arg(_arg) {} private: Obj() = delete; int arg; }; struct T { T() {} ~T() {} union { Obj obj; }; }; int main() { // This would complain about Obj not having a default constructor. //std::vector<Obj> data(1); // This works because the union only reserves space in T, it doesn't initialize obj. // Now we've allocated space for an Obj, without forcing a default constructor. std::vector<T> data(1); }
-
Constant Expressions:
We can now pass expressions where we could not before:
-
Given:
#include <unistd.h> #include <stdio.h> struct HttpRequest { char buf[12]; }; struct HttpResponse { char buf[16]; }; template <size_t size> struct Buffer { char buf[size]; };
-
Doesn't work:
#include <algorithm> int main() { // This won't compile because std::max is not a constexpr. Buffer<std::max(sizeof(HttpRequest), sizeof(HttpResponse))> buf; printf("size of buf = [%ld]\n", sizeof(buf)); }
-
Now we can do:
template <typename T> constexpr const T& max(const T& lhs, const T& rhs) { return lhs > rhs ? lhs : rhs; } int main() { Buffer<max(sizeof(HttpRequest), sizeof(HttpResponse))> buf; printf("size of buf = [%ld]\n", sizeof(buf)); }
-
-
Delegating Constructors:
We can now simplify classes by turning repeated logic used by multiple constructors into constructor delegation:
- Before:
// We used to also use a private init() routine to avoid this pattern. // Still, constructor delegation is more clean and concise! class Foo { public: Foo (int arg1, int arg2, int arg3) { CHECK(arg1 > 0) << "Foo::arg1 must be > 0"; ... } Foo (const std::string& name, int arg1, int arg2, int arg3) { CHECK(arg1 > 0) << "Foo::arg1 must be > 0"; ... } Foo (const Bar& other) { arg1 = other.arg1; ... CHECK(arg1 > 0) << "Foo::arg1 must be > 0"; } private: int arg1, arg2, arg3; };
- Now:
// Delegate construction and perform the logic once! class Foo { public: Foo (int arg1, int arg2, int arg3) { CHECK(arg1 > 0) << "Foo::arg1 must be > 0"; ... } Foo (const std::string& name, int arg1, int arg2, int arg3) : Foo(arg1, arg2, arg3) { ... } Foo (const Bar& other) : Foo(other.arg1, other.arg2, other.arg3) { ... } private: int arg1, arg2, arg3; };
-
Thread-Local Storage:
We can now use standardized thread-local storage:
- We can use constant expressions to initialize them
- They are much more efficient
- They are standardized! :-)
- Before:
#include <stout/thread.hpp> ThreadLocal<bool>* my_local_data = new ThreadLocal<bool>();
- Now:
__thread bool my_local_data = false;
-
Template Alias-Declarations:
from: https://gcc.gnu.org/gcc-4.7/changes.html
G++ now implements C++11 alias-declarations.
template <class T> using Ptr = T*; Ptr<int> ip; // decltype(ip) is int*
These are useful when we want to alias types in templates that have not been fully specialized yet.
-
Non-Static Data Member Initializers:
from: https://gcc.gnu.org/gcc-4.7/changes.html
G++ now implements C++11 non-static data member initializers.
struct A { int i = 42; } a; // initializes a.i to 42
-
Lots More:
Check out:
- The matrix: https://gcc.gnu.org/projects/cxx0x.html
- GCC 4.5: https://gcc.gnu.org/gcc-4.5/changes.html
- GCC 4.6: https://gcc.gnu.org/gcc-4.6/changes.html
- GCC 4.7: https://gcc.gnu.org/gcc-4.7/changes.html
Last active
August 29, 2015 14:18
-
-
Save jmlvanre/8425725ee72d41917b2d to your computer and use it in GitHub Desktop.
New GCC Features 4.4 => 4.7
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment