Fab*_* A. 3 constructor temporary c++11 c++98
我想测试一个临时对象是否至少与持有const引用的临时对象一样长,所以我想出了这个例子.
#include <iostream>
struct Test {
Test() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
~Test() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
struct Holder {
Holder(const Test& t):m_t(t) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
~Holder() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
const Test& m_t;
};
int main() {
Holder(Test());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,我很惊讶地看到编译器实际上已经优化了整个事情,就像在codebolt上看到的那样
但是,如果我真的给临时的名字,通过改变线
Holder(Test());
Run Code Online (Sandbox Code Playgroud)
成
Holder h((Test()));
Run Code Online (Sandbox Code Playgroud)
然后它"神奇地"起作用:codebolt.
情节扭曲:如果我切换到c ++ 11并使用类的支撑列表初始化Holder,那么无论我是否为临时名称赋予构造函数,都不会省略构造函数.见codebolt一次.
那么这里有什么问题?我的印象是,带有副作用的构造函数永远不会被省略,但我显然错过了版本之间变化的标准的重要部分.
任何人都可以给我一个提示吗?
这是最令人烦恼的解析问题:Holder(Test());声明一个名为return的函数Test,它返回Holder并接受0个参数.
用g ++代码如下:
#include <iostream>
#include <type_traits>
struct Test {};
struct Holder { Holder(Test); };
template<class T>
char const* f() { return __PRETTY_FUNCTION__; }
int main() {
Holder(Test());
std::cout << f<decltype(&Test)>() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出:
const char* f() [with T = Holder (*)()]
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方法是使用C++ 11大括号进行初始化:Holder(Test{});或Holder{Test{}};.
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |