#include <iostream>
struct Box
{
Box() { std::cout << "constructor called" << std::endl; }
Box(const Box&) { std::cout << "Copy constructor called" << std::endl; }
Box(Box&&) { std::cout << "Move constructor called" << std::endl; }
void run() const { std::cout << "Run" << std::endl;}
};
int main()
{
Box a(Box());
a.run();
}
Run Code Online (Sandbox Code Playgroud)
(演示)
在上面的代码我期待任一Copy Constuctor
或Move Constructor
在经过匿名对象被调用Box()
作为参数.但他们都没有被召唤.原因可能是copy elision
.但是甚至没有为匿名对象调用构造函数A()
.实际上,上面的代码没有编译,并且在调用run()
函数编译器时给出了以下错误.
a.cpp: In function ‘int main()’:
a.cpp:28:7: error: request for member ‘run’ in ‘a’, which is of non-class type ‘Box(Box (*)())’
a.run();
Run Code Online (Sandbox Code Playgroud)
那么当我们输入Box a(Box())
正在发生的事情时?正在创造什么?
YSC*_*YSC 15
这是最令人烦恼的解析案例.什么东西可以解析为函数声明,它是.
Box a(Box())
Run Code Online (Sandbox Code Playgroud)
是一个函数的声明,命名为a
将类型的函数Box (*)()
作为参数并返回一个Box
.
解决方案是使用(C++ 11中的新增功能)聚合初始化来构造对象:
Box a{Box{}}
Run Code Online (Sandbox Code Playgroud)
(演示)
MVP以最简单的形式讨论了这个stackoverflow问题最烦恼的解析:为什么不是A a(()); 工作?
如果你有一个表达式,那么它是有效的.例如:
Run Code Online (Sandbox Code Playgroud)((0));//compiles
要了解有关如何定义语言以及编译器如何工作的更多信息,您应该了解正式语言理论或更具体的上下文无关语法(CFG)和相关材料(如有限状态机).如果你对此感兴趣,虽然维基百科页面还不够,你将不得不得到一本书.
归档时间: |
|
查看次数: |
316 次 |
最近记录: |