为什么对于这个未命名的临时构造函数被省略,具有正常初始化的副作用而不是括号列表初始化?
Why is constructor being elided for this unnamed temporary with side effects with normal initialization but not with braced list initialization?
我想测试一个临时对象是否至少与持有对它的 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;
}
然而,我很惊讶地看到 编译器实际上已经优化了整个东西,正如在 codebolt
上看到的那样
但是,如果我实际上给临时文件一个 name,通过更改行
Holder(Test());
进入
Holder h((Test()));
然后 "magically" 有效:codebolt.
情节扭曲:如果我切换到 c++11 并使用 Holder
class 的花括号列表初始化,则构造函数不是无论我是否给临时名称命名,都将被删除。再看codebolt。
这是怎么回事?我的印象是永远不会省略具有副作用的构造函数,但我显然遗漏了版本之间更改的标准的重要部分。
有人可以给我提示吗?
这是 most vexing parse issue:Holder(Test());
声明了一个名为 Test
的函数,该函数 returns 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';
}
输出:
const char* f() [with T = Holder (*)()]
一个简单的解决方法是使用 C++11 大括号进行初始化:Holder(Test{});
或 Holder{Test{}};
.
我想测试一个临时对象是否至少与持有对它的 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;
}
然而,我很惊讶地看到 编译器实际上已经优化了整个东西,正如在 codebolt
上看到的那样但是,如果我实际上给临时文件一个 name,通过更改行
Holder(Test());
进入
Holder h((Test()));
然后 "magically" 有效:codebolt.
情节扭曲:如果我切换到 c++11 并使用 Holder
class 的花括号列表初始化,则构造函数不是无论我是否给临时名称命名,都将被删除。再看codebolt。
这是怎么回事?我的印象是永远不会省略具有副作用的构造函数,但我显然遗漏了版本之间更改的标准的重要部分。
有人可以给我提示吗?
这是 most vexing parse issue:Holder(Test());
声明了一个名为 Test
的函数,该函数 returns 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';
}
输出:
const char* f() [with T = Holder (*)()]
一个简单的解决方法是使用 C++11 大括号进行初始化:Holder(Test{});
或 Holder{Test{}};
.