统一初始化语法
C++是个语法特别复杂的语言,在语法分析中时常会出现歧义,例如嵌套模板参数歧义问题:
vector<vector<int>> vec
在有的编译器上会被解析为vector< vector < int >>vec,也就是把>>当成右移操作符了,不过C++11已经解决这个问题了。咋解决的呢,简单地说,编译器把对>>的分析延迟到语法分析阶段(原来是在词法分析阶段),词法分析器是把”>>”直接当成两个”>”传给了语法分析器,然后在语法分析中如果匹配了template-argument-lis语法,第一个”>”符号会被直接认为是模版结束符,而不是大于,也不是位移符号。
而另一种语法上的歧义是下面这种情况:
class A
{
public:
A(){};
};
class B
{
public:
B(const A& t){};
int getNum(){ return 0; }
};
int _tmain(int argc, _TCHAR* argv[])
{
B test(A());
cout << test.getNum();
return 0;
}
问题出在 B test (A()); 这句话,因为它有两种理解方式:
- test 是个B类型的对象。 它使用A对象进行初始化。
- test 是个返回值为B类型对象的函数,它有个类型为A的参数。
我们代码的意图是test是个对象,然而我的VS却把它理解成一个函数,并且告诉我:
error C2228: “.getNum”的左边必须有类/结构/联合
解决的办法就是使用C++11 提供的万能初始化钥匙(统一的初始化语法):
B test{A()};
回过头来看看发生歧义的原因:
- C/C++中函数声明与定义是可以分开的。函数使用前声明就行。
- 函数声明可以放在函数中。
- C++函数声明的时候,形参可以只有类型而没有名称。
- C++函数声明的参数名在类型后面可以加上(),如void max (int ( ),int ( ))
(完)
作者:melonstreet
出处:https://www.cnblogs.com/QG-whz/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。