These hidden features were spotted by C++ programmers during their endeavors. See if they hold for you.
C++ is getting hotter with every passing day. Being a multi-paradigm language, these hidden features of C++ are basically just clever uses of its existing facilities. There are more such facilities as well and we would love to hear if out readers have something to add.
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; };
C++ is getting hotter with every passing day. Being a multi-paradigm language, these hidden features of C++ are basically just clever uses of its existing facilities. There are more such facilities as well and we would love to hear if out readers have something to add.
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
// void (*f(void(*p)()))(int); // same
id
// int (*p)[2] = new int[10][2]; // same
id
// void (C::*p)(int) = 0; // same
id
It helps decrypting C++ declarations greatly!
// boost::identity is pretty much the same
template
struct id { typedef T type; };