Я хотел проверить, будет ли временный объект жить по крайней мере до тех пор, пока временный объект, который содержал ссылку на константу, поэтому я придумал этот пример.Почему конструктор исключается для этого неназванного временного с побочными эффектами с нормальной инициализацией, но не с инициализацией с сохраненным списком?
#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
Но, если я на самом деле дать имени к временный, изменив строку
Holder(Test());
в
Holder h((Test()));
Тогда это «магически» работает: codebolt.
сюжетный поворот: при переходе на C++ 11 и использовать приготовилась инициализация списка для Holder
класса, то конструктор не опущен независимо от того, даю ли я имя на временный или нет. См. Также codebolt.
Так в чем дело? У меня создалось впечатление, что конструкторы с побочными эффектами никогда не будут устранены, но я, очевидно, пропустил важный элемент стандарта, который изменился между версиями.
Может ли кто-нибудь дать мне подсказку?
'Держатель (Test());' - вариант наиболее неприятного разбора. – cpplearner
О, черт! Думать, что я принял во внимание самый неприятный синтаксический разбор в том же примере, который я дал, с именованной переменной. –
Это дополнительная пара круглых скобок, которая блокирует самый неприятный синтаксический разбор. 'Holder h (Test());' является самым неприятным анализом, 'Holder h ((Test())),' is not. – Oktalist