本文主要是介绍Most vexing parse(最烦人的解析),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Most vexing parse(最烦人的解析)
- 引言
- 错误的方式
- Most vexing parse 解释
- 证明
- 如何避免
引言
Most vexing parse 是 effective c++ 书中写到的,写本文是为了讲清这到底是什么.
错误的方式
#include <iostream>
class A { public:A(const std::string& name){std::cout << name << std::endl;}
};int main()
{char szTemp[] = "test";A a(std::string(szTemp));//A a(std::string())//同样没有输出return 0;
}
上面写了一个简单的类,构造函数允许传入一个string类型的引用,然后输出。
在main
函数中我们的本意是创建一个A类型的对象
,并且传入szTemp的string
,让其在构造函数中输出
。
但是却发现什么也没有输出,这是什么原因呢?
Most vexing parse 解释
在C++中,如果出现 T1 t1Name(T2(t2Name))
,C++会将它解释成T1 t1Name(T2 t2Name)
函数声明。
拿上面弄得栗子讲:
A a(std::string(szTemp))
被解释成了 A a(std::string szTemp)
的函数声明。
如果我们将A a(std::string(szTemp))
替换成A a(std::string("test"))
,或者将A a(std::string())
替换成A a(std::string(""))
就不会有任何问题。
证明
通过打印 std::cout << typeid(a).name();
可以发现类型根本不是class a
,而是一个function.
下面的代码我们将A a(std::string(szTemp))
真正定义出来。
#include <iostream>
class A { public:A(const std::string& name){std::cout << name << std::endl;}
};char szTemp[] = "test";A a(std::string(szTemp)){//这里的szTemp并不是全局变量的szTemp//而是函数形参,还记得上面说过//被解释成了 A a(string szTemp)std::cout << szTemp + " 新的输出" << std::endl;return A(szTemp);
}int main()
{//这里的a是function,会返回一个A类型的对象//所以不存在T1 t1name,T2 t2name 同时出现的问题。这是一个赋值语句。char test[]="haha";A obj = a(std::string(test));return 0;
}
输出结果:
test 新的输出
test
如何避免
使用C++的方式来传参。
- A a{ std::string(szTemp) };
- 先创建string字符串
std::string str(szTemp) ;
A a(str);
- 直接使用常量
A a(std::string(“test”) );
这样仅仅是T1 t1name(T2(常量))
只要避免T1 t1name T2 t2name 同时出现即可。
这篇关于Most vexing parse(最烦人的解析)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!