
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (78) « Первая ... 44 45 [46] 47 48 ... 77 78 ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#676
,
|
|
Radagast, а зачем?
|
Сообщ.
#677
,
|
|
|
Цитата Qraizer @ Radagast, а зачем? Ну в общем случае, тебе может быть нужно что-то отдать/удалить/отписаться/"отрегистрироваться" и т.д. и т.п. только в том случае, если выполнился делегирующий конструктор. Понятно, что дизайн в этом случае, скорее всего, кривой, но тем не менее... Добавлено ![]() ![]() class A { public: A() : A(10) { // тут код с возможным исключением // регистрируемся где-нибудь } ~A() { // тут нужно узнать, регистрировались ли мы :( } private: A(int a); int ma; }; |
Сообщ.
#678
,
|
|
|
Цитата niXman @ Уххх. Аццкая фича какая то. C:\test>g++ -std=c++0x delegat.cpp -odelegat C:\test>delegat ~SomeType() catching exception C:\test> ![]() |
Сообщ.
#679
,
|
|
|
Цитата Повстанець @ Надеюсь хоть без делигирующих конструкторов всё будет по старому. Конечно. Собственно, делигирующие конструкторы - это уже и не конструкторы получаются, а специальная над ними надстройка... Может стоило синтаксис даже новый ввести... |
![]() |
Сообщ.
#680
,
|
|
Я думаю, это естественно. Конструкторы находятся в весьма особом положении по сравнению с другими методами. Все остальные методы имеют право опираться на инварианты класса, тогда как конструкторы такого права не имеют, они эти инварианты создают. Если декомпозиция приводит в выделению общих конструирующий действий в отдельные методы, такие методы становятся тоже специальными, что добавляет путаницы, особенно вкупе с полиморфизмом. Вот и нечего. Теперь в роли таких методов будут делегирующие конструкторы.
|
Сообщ.
#681
,
|
|
|
Цитата Radagast @ вопрос теперь в том, как в деструкторе отличить, какие конструкторы успели отработат А в чем проблема? Конструктор ссылающийся на другой конструктор, сам созданием инвариантов уже не занимается. К моменту начала выполнения его тела объект уже создан, и он отрабатывается как обычный метод. Если исключение выбросится из конструктора, что в списке инициализации (делегируемого), объект незавершен - деструктор не вызывается. Если исключение выбросится в теле такого делегирующего конструктора, то как и в обычном методе разматывается стек и вызывается деструктор. Добавлено Даже поведение компилятора менять не надо |
Сообщ.
#682
,
|
|
|
Менять, конечно же, не надо. Все так и должно быть. Вопрос только в том, насколько это будет путать начинающих. Казалось бы, фишка как раз для упрощения, а выходит даже наоборот...
|
![]() |
Сообщ.
#683
,
|
|
Разве наоборот? Один конструктор же уже отработал, инварианты в порядке, почему деструктор не должен быть вызван? Некий код, делающий дополнительно ещё что-то, не должен нарушать инварианты, а если же и нарушает временно, так ситуация ничем не отличается от других методов.
|
Сообщ.
#684
,
|
|
|
Цитата Qraizer @ почему деструктор не должен быть вызван? Должен. Другое дело, что теперь появились конструкторы, которые не занимаются конструированием. Что как-то не очень логично ![]() |
![]() |
Сообщ.
#685
,
|
|
Хм... ну как сказать... Инварианты инвариантами, но ведь помимо создания инвариантов и определённости состояния на конструкторы возлагается также конкретность этой определённости. Иначе зачем их перегружать? Сконструировали, затем проинициализировали. Получится Дельфи. Т.к. эффективнее сконструировать сразу в нужном состоянии, нежели сначала в дефолтовом, а только затем перевести в нужное, то перегрузка конструкторов оправдана. Тут то же самое. Уже есть конструктор, который создаёт инвариант, остаётся только дозадать состояние экземпляра.
Формально да, есть определённый диссонанс. Думаю, со временем придём к выводу, что делегируемые конструкторы обычно не должны быть публичными. |
Сообщ.
#686
,
|
|
|
![]() ![]() auto x = { 1, 2, 3, 4, 5 }; // ok a has type std::initializer_list<int> Должен ли выводится тип для std::initializer_list<std::initializer_list<int>>: ![]() ![]() auto x = { {1, 2}, {3, 4, 5} }; ? |
Сообщ.
#687
,
|
|
|
Цитата D_KEY @ Должен ли выводится тип для std::initializer_list<std::initializer_list<int>>: Вроде как нет. |
Сообщ.
#688
,
|
|
|
по опыту - нет.
по стандарту - хз. |
Сообщ.
#689
,
|
|
|
gcc не выводит, хотелось бы узнать, как по стандарту. А то я сам не могу понять должен или нет
![]() Вообще было бы логичным, чтобы выводил... Добавлено Обидно, если нельзя, потому как даже "руками" не сделать: ![]() ![]() std::initializer_list<auto> x = { {1, 2, 3}, {4, 5, 6} }; // так нельзя |
![]() |
Сообщ.
#690
,
|
|
Думаю, нет.
Цитата 7.1.6.4 auto specifier 6 ... Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>. The type deduced for the variable d is then the deduced type determined using the rules of template argument deduction from a function call (14.9.2.1), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed. ... Цитата 14.9.2.1 Deducing template arguments from a function call Внутренний std::initializer_list<> - это невыводимый контекст.1 Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list<P'> for some P' and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.9.2.5). P.S. Это не последний драфт, последний сейчас вне доступа. |