Wednesday, 25 December 2013

5 Hidden Features Of C++ That You May Find Interesting


1. While the ternary operator (?:) is well known, many don’t realise that it can also be used as lvalues.

x = (y < 0) ? 10 : 20;
(a == 0 ? a : b) = 1;

Otherwise, you would be writing this as,

if (a == 0)
a = 1;
else
b = 1;

2. The namespace alias is pretty easy to miss. Once you know about it though, you will start recognising it everywhere. It is especially useful when you’rr writing a large code with a lot of namespace hierarchies.

namespace x = boost::filesystem;

x::path myPath(strPath, fs::native );

3. Variables aren’t the only ones that can be declared in the init part of functions. You can also declare classes and other functions.

for(struct { int x; float y; } loop = { 1, 2 }; ...; ...) {
...
}

4. The unary + operator can be used in order to promote or decay a number of things. See below for some examples.

+EnumeratorValue: This gives your enumerator value a perfect integer type, which lets it fit its value. This is quite useful for implementing overloaded operators for enumeration.

Passing a temporary value to a variable: You can create a temporary value for a variable using this operator. For example, if you have a class that uses an in class static initializer without any out of class definition, but sometimes the system fails to link.

struct Foo {
static int const value = 42;
};

template
void f(T const&);

int main() {
// fails to link and tries to get the address of "Foo::value"!
f(Foo::value);

// works - pass a temporary value
f(+Foo::value);
}

Decay an array to a pointer: The operator also works when you want to pass two values to a function.

template
void f(T const& a, T const& b);

int main() {
int a[2];
int b[3];
f(a, b); // won't work! different values for "T"!
f(+a, +b); // works! T is "int*" both time
}

5. You must know the id/identity metafunction. Now check out this usecase for it, which is for non-template cases.

// void (*f)(); // same
id::type *f;

// void (*f(void(*p)()))(int); // same
id::type *f(id::type *p);

// int (*p)[2] = new int[10][2]; // same
id::type *p = new int[10][2];

// void (C::*p)(int) = 0; // same
id::type C::*p = 0;

It helps decrypting C++ declarations greatly!

// boost::identity is pretty much the same
template
struct id { typedef T type; };

No comments:

Post a Comment