你可能会感兴趣的 5 个隐藏的 C++ 语言特性

jopen 10年前

一天又一天,C++ 是越来越火起来了. 作为一种范式覆盖语言,C++的这些隐藏特性基本上就基本上只是对其现有的基础设施的灵活使用. 其实还有更多的这样的设施,而我们也乐于听见读者对此能够有所补充.

#1. 众所周知的三元运算符 (?:), 许多人并没有意识到它可以作为左值来使用.

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

不这样的话,你就只能得像下面这样写了, 

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

#2.  命名空间别名这一特性你也可能会很容易的错过. 一旦你了解了它,你就会认识到它是无所不在的. 当你在在编写一端带有许多命名空间层级结构的大型代码时,它是特别的有用啊. 

namespace x = boost::filesystem;

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

#3.  变量并不是唯一能够在函数的初始部分被声明的东西. 你也可以声明类和其它的函数.

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

#4.    一元的 + 运算符可以被用来增进或者消退某些东西的量. 见下面的一些示例.

+EnumeratorValue: 这能给予你的枚举值一个完美的整形, 其能让枚举值适合它的值. 这在实现针对枚举的操作符重载时相当的有用.

向变量传递一个临时的值: 你可以为使用这个操作符的变量创建一个临时的值. 例如,如果你有一个使用了一个没有任何外部的类定义的内部的类静态初始化器的类,但有时系统会链接失败,这样的类的话.

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);
}

递减一个数组的指针: 操作符也能在你想要传递两个值到一个函数中时起作用.

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 . 你必须知道有 id/标识 的元函数。现在就看看这个针对他的用例吧,其适用于没有模板的情况.

// 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 是一样的
template 
struct id { typedef T type; };