问题1
有网友问这样一个问题:
Is there any way to use QString as a parameter in switch case as shown below. QString str; switch(str) { case "A": break; case "B": break; }
潜意识告诉我这样肯定不行,可是证据呢?连自己都说服不了,难受。
只好翻翻C++标准了。还好,很容易就找到了(ISO C++ 6.4 节):
- switch 语句中的“条件”,必须是
- 整数或enum类型的变量,或
- 可以隐式转换成整数或enum类型的变量
由于QString没有 operator int() 这类的成员函数,故不可以。
标准原文:
- The value of a condition that is an initialized declaration in a switch statement is the value of the declared variable if it has integral or enumeration type, or of that variable implicitly converted to integral or enumeration type otherwise.
恩,那么case后面可以是“A”这种东西么?ISO C++ 6.4.2,对此有规定:
- case 后面必须是整数常量
标准原文:
-
Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be an integral constant.
问题二
void main(){ int a = a; } A compiler通过, linker不能通过. B compiler不能通过 C 视乎具体compiler而定
咱们忽略 main 函数的这个不规范的写法,假定它的意图就是问 int a = a;这一句。
这个东西有没有问题?翻标准,恩 ISO C++ 3.3.2
没任何问题:
int x = 12; { int x = x; }
第二个x将使用它自己的值(尽管是不确定的值)进行初始化。与第一个x无关。
标准中还给出的其他的例子:
const int i = 2; { int i[i]; }
恩,和先前不同,块作用域内定义了一个两个整数元素的数组。
const int x = 12; { enum { x = x }; }
恩,对于枚举量,x的值初始化为12。也和先前不同。
标准原文(只贴出一段):
-
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. — end example ]
问题三
使用typeid实验结果是: typeid(int()) != typeid(int) typeid(int()) != typeid(i) // int i so... int()是啥东西?
恩,int() 是什么东西呢?
当我们这样写时,应该就比较清楚了
int a();
是一个函数的声明,那么 int() 就是函数类型了。
只是,有个疑问,楼主既然用到typeid了,为何不使用 type_info::name() 来输出类型信息看看呢?
于是写个例子:
#include <stdio.h> #include <typeinfo> int main() { printf("%s\n", typeid(int()).name()); printf("%s\n", typeid(int).name()); return 0; }
用GCC编译运行(如果用的MSVC,生成的可读性很好的字符串)
FivE i
啊,难怪,原来这个和名字改编几乎一样的东西,很难读懂。既然输出都输出了,试试读读看:
GCC4使用的 Itanium C++ ABI,于是找到这个网页:
F...E | 函数 |
i | 返回值为 int |
v | 参数为 void |
恩,简单的函数还好办,如果复杂的类型还真麻烦。幸好,GCC提供有demangle的函数:
恩,改写如下:
#include <stdio.h> #include <typeinfo> #include <cxxabi.h> int main() { char * realname = abi::__cxa_demangle(typeid(int()).name(), 0, 0, 0); printf("%10s ==> %15s\n", typeid(int()).name(), realname); realname = abi::__cxa_demangle(typeid(int(*)()).name(), 0, 0, 0); printf("%10s ==> %15s\n", typeid(int(*)()).name(), realname); realname = abi::__cxa_demangle(typeid(int).name(), 0, 0, 0); printf("%10s ==> %15s\n", typeid(int).name(), realname); return 0; }
结果:
FivE ==> int ()() PFivE ==> int (*)() i ==> int