私は、一時オブジェクトが少なくともconst参照を保持している一時オブジェクトと同じ長さであるかどうかをテストしたいので、この例を考えました。私は実際に名前を与える場合、codebolt通常の初期化では副作用のあるこの名前のない一時的なものに対してはコンストラクタが省略されていますが、リストの初期化はされていません。
に見えるしかし、することができますよう
#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;
}
しかし、私は、コンパイラが実際に全部を最適化していたことを見て非常に驚きました
にラインHolder(Test());
を変更することで、一時的
それは "魔法のように"動作します:codebolt。
プロットツイスト:私はC++ 11に切り替えて、Holder
クラスのブレースリストの初期化を使用する場合は、コンストラクタは、私は一時的かどうかに名前を与えるかどうかに関係なく省略されていません。再びcodeboltを参照してください。
ここには何がありますか?私は、副作用のあるコンストラクタは決して切れないだろうという印象を受けていましたが、私は明らかにバージョン間で変わった重要な標準を欠いています。
誰でも私にヒントを教えてもらえますか?
'Holder(Test());'は、最も厄介な構文解析の変形です。 – cpplearner
ああ!私が指定した例で、名前のついた変数を使って、最も厄介な解析を考慮に入れたと思う。 –
これは、最も厄介な解析を抑制する余分な括弧のペアです。 'ホルダーh(テスト());'は最も厄介な構文解析であり、 'ホルダーh((テスト)))'はそうではありません。 – Oktalist