Re[3]: No more ugly functors
От: folk Россия  
Дата: 23.11.04 23:11
Оценка: +1
Здравствуйте, vdimas, Вы писали:

WH>>Здравствуйте, WolfHound, Вы писали:


WH>>Но при использовании break оптимизатор не смог избавится от оверхеда


V>естественно, потому как логика изменения переменной _fe_break заранее не известна в случае применения break. Если сделать допущение и разделить аргументы типа и переменной, т.е. так:

V>
V>foreach(int, i, vec) { ... }
V>


V>то последней конструкцией не будет for (где мы подставляли объявление "int i"), и тогда break и continue работают естественным образом, без оверхеда.


V>вот болванка:


V>
V>int _tmain(int argc, _TCHAR* argv[])
V>{

V>    std::vector<int> v;
V>    v.push_back(1);
V>    v.push_back(2);
V>    v.push_back(3);
V>    v.push_back(4);

V>    int s=0;

V>    if(bool _fe_break=false) {} else
V>        for(int i;_fe_break==false; _fe_break=true)    // тут просто объявили
V>            for(const foreach_detail::wrapper_holder
V>                &_fe_cur=foreach_detail::wrap(v.begin()),
V>                &_fe_end=foreach_detail::wrap(v.end());
V>                !foreach_detail::is_wrapped_equal(_fe_cur, _fe_end, v.end());
V>                ++foreach_detail::unwrap(_fe_cur, v.end()))
V>                    if(i=*foreach_detail::unwrap(_fe_cur, v.end()), true)  // тут if а не for
V>    {
V>        if(i==2) break;
V>        s+=i;
V>    }

V>    std::cout <<s;
V>    return 0;
V>}
V>


V>break и continue в ассемблерном листинге без оверхеда.


Во-1х вводится лишняя запятая в объявлении макроса, а мы хотим синтаксически приблизится к "нормальному" foreach.

Во-2х такой подход принципиально не прет. Мы хотим иметь возможность объявлять ссылку на элемент последовательности ( FOR_EACH(int& i, vec) ) чтобы изменять эти элементы. А ссылку нельзя переназначить на другой элемент. Значит курсор (не знаю как его правильно обозвать) нельзя отдельно объявлять и отдельно присваивать значение. Объявление курсора не может находиться в if, т.к. неизвестно будет ли тип кусора неявно приводим к bool, а тем более будет ли приводим конкретно к true.

Написал путано, но попробуй сделать чтобы твой подход работал и со ссылками, и все станет ясно. По-моему (и WH видимо также считал) for — единственная подходящая конструкция для объявления курсора.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[4]: No more ugly functors
От: vdimas Россия  
Дата: 24.11.04 13:58
Оценка: -1
Здравствуйте, folk, Вы писали:

F>Во-1х вводится лишняя запятая в объявлении макроса, а мы хотим синтаксически приблизится к "нормальному" foreach.


For Each пришел из VB, вообще-то, там это записывалось так:
Dim i as Integer
For Each i in col
' ...
Next


т.е. так же можно вынести объявление и в С++:
int i;
foreach(i, vec) s+=i;



F>Во-2х такой подход принципиально не прет. Мы хотим иметь возможность объявлять ссылку на элемент последовательности ( FOR_EACH(int& i, vec) ) чтобы изменять эти элементы.


все ясно, тут не возразишь...
но мне чисто внутренне приятней иметь 3 ассемблерные инструкции для организации цикла, вместо 6-ти (при использовании break)

свой вариант я уже оформил и именно в том виде, как показал выше — с предварительным объявлением.
Ok, беру ваш вариант, и называю его foreach_ref для тех случаев, где потребуется ссылка. (просто у меня чаще всего в коллекциях указатели хранятся, или их браться smart_ptr<они же>, т.е. я про ссылки не учел)

F>Объявление курсора не может находиться в if, т.к. неизвестно будет ли тип кусора неявно приводим к bool, а тем более будет ли приводим конкретно к true.


там у меня не объявление курсора, а присвоение. через запятую у меня там true.

Если бы была допустима такая конструкция:
if((int i=*it), true) {}
но она не допустима
Re[5]: No more ugly functors
От: folk Россия  
Дата: 25.11.04 02:31
Оценка:
Здравствуйте, vdimas, Вы писали:

V>все ясно, тут не возразишь...

V>но мне чисто внутренне приятней иметь 3 ассемблерные инструкции для организации цикла, вместо 6-ти (при использовании break)

Ага, не очень приятно это осозновать, но имхо break используется раз в пятилетку.

V>свой вариант я уже оформил и именно в том виде, как показал выше — с предварительным объявлением.

V>Ok, беру ваш вариант, и называю его foreach_ref для тех случаев, где потребуется ссылка. (просто у меня чаще всего в коллекциях указатели хранятся, или их браться smart_ptr<они же>, т.е. я про ссылки не учел)

На всякий случай замечу, что создание копии умного указателя скорее всего обойдется дороже, чем принять его по константной ссылке и (если используется break) потратить вхолостую эти три инструкции.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[6]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 25.11.04 08:37
Оценка:
Здравствуйте, folk, Вы писали:

F>Здравствуйте, vdimas, Вы писали:


V>>все ясно, тут не возразишь...

V>>но мне чисто внутренне приятней иметь 3 ассемблерные инструкции для организации цикла, вместо 6-ти (при использовании break)

F>Ага, не очень приятно это осозновать, но имхо break используется раз в пятилетку.


я поражаюсь люди, откуда такие сведения???
я, например, заметил за собой довольной частое использование. откуда статистика?
... << RSDN@Home 1.1.3 stable >>
Re[7]: No more ugly functors
От: folk Россия  
Дата: 25.11.04 12:00
Оценка:
yxiie:

> F>Ага, не очень приятно это осозновать, но имхо break используется раз в пятилетку.

>
> я поражаюсь люди, откуда такие сведения???
> я, например, заметил за собой довольной частое использование. откуда статистика?

это была метафора, художественное преувеличение

Сейчас поискал по текущему проекту, нашел 192 looping statement и 77 break, из них 66 находятся внутри switch. Получаем 192/11, т.е. 1 break на 17.(45) циклов.

Понятно что эти цифры ни о чем кроме этого самого проекта не говорят. Просто самому интересно стало.
Posted via RSDN NNTP Server 1.9 gamma
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[6]: No more ugly functors
От: vdimas Россия  
Дата: 28.11.04 01:50
Оценка:
Здравствуйте, folk, Вы писали:

F>На всякий случай замечу, что создание копии умного указателя скорее всего обойдется дороже, чем принять его по константной ссылке и (если используется break) потратить вхолостую эти три инструкции.


На всякий случай замечу, что пройтись по коллекции с умными указателями всегда удавалось обычным указателем

break я слишком часто юзаю, почти в 1/3 случаев. с ним алгоритмы самые короткие.
Re[7]: No more ugly functors
От: folk Россия  
Дата: 28.11.04 09:24
Оценка:
vdimas:

> F>На всякий случай замечу, что создание копии умного указателя скорее всего обойдется дороже, чем принять его по константной ссылке и (если используется break) потратить вхолостую эти три инструкции.

>
> На всякий случай замечу, что пройтись по коллекции с умными указателями всегда удавалось обычным указателем

Зависит от указателей, которые используешь. Бустовые умные не приводимы к "глупому" указателю, надо использовать get(). Так что с ними в FOR_EACH придется создавать копию.

> break я слишком часто юзаю, почти в 1/3 случаев. с ним алгоритмы самые короткие.
Posted via RSDN NNTP Server 1.9 delta
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[7]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 14.01.05 19:03
Оценка:
Здравствуйте, folk, Вы писали:

Ну что за беда у меня с этими foreach
вариант WolfHound'a время от времени выдает run-time check failure — stack around 'xxx' variable corrupted,
у меня подозрения, что он пропускает больше прогонов цикла, чем нужно, а твой вариант
даже не компилится VC 7.0

f:\...xxx.cpp(24) : error C2667: 'foreach_detail::begin' : none of 2 overloads have a best conversion
f:\Work\prg\unnamed\include\0-utility\lang\foreach.h(281): could be 'foreach_detail::wrapper<boost::range_const_iterator<Range>::type> foreach_detail::begin(const Range &)'
f:\Work\prg\unnamed\include\0-utility\lang\foreach.h(274): or 'foreach_detail::wrapper<boost::range_iterator<Range>::type> foreach_detail::begin(Range &)'
while trying to match the argument list '(const std::list<_Ty,_Ax>)'
with
[
_Ty=Phoenix::PBoundedObject,
_Ax=std::allocator<Phoenix::PBoundedObject>
]


не может выбрать из этих двух вариантов:
template<class Range>
wrapper<typename boost::range_iterator<Range>::type>
    begin( Range& range )
{
    return boost::begin( range );
}

template<class Range>
wrapper<typename boost::range_const_iterator<Range>::type>
    begin(Range const& range )
{
    return boost::begin( range );
}


компилировал такое:
const list<PBoundedObject>& objects;
foreach (const PBoundedObject& i, objects)


Кстати я уже делал замечания по поводу этого foreach, но похоже не в этой ветке.
В твоей реализации эта ошибка тоже присутствует:

F>#define FOR_EACH( ElementDecl, Range )\
F>    if( bool _fe_break = false ) {}\
F>    else\
F>    for( foreach_detail::holder const\
F>              &_fe_current = foreach_detail::begin(Range)\
F>            , &_fe_last    = foreach_detail::end(Range)\

здесь нужно не
F> ; _fe_current(Range) != _fe_last(Range) && (_fe_break = !_fe_break)\
а
F> ; (_fe_break = !_fe_break) && _fe_current(Range) != _fe_last(Range)\

F>        ; ++_fe_current(Range)\
F>    )\
F>    for( ElementDecl = *_fe_current(Range); _fe_break; _fe_break = false )\
F>// end macro


а то на таком примере будет boom:

foreach (int& i, obj->ints) {
    obj=NULL;
    break;
}
... << RSDN@Home 1.1.3 stable >>
Re[8]: No more ugly functors
От: Костя Ещенко Россия  
Дата: 15.01.05 08:52
Оценка:
yxiie wrote:

> Ну что за беда у меня с этими foreach

> вариант WolfHound'a время от времени выдает run-time check failure — stack around 'xxx' variable corrupted,
> у меня подозрения, что он пропускает больше прогонов цикла, чем нужно, а твой вариант
> даже не компилится VC 7.0
>
>

> f:\...xxx.cpp(24) : error C2667: 'foreach_detail::begin' : none of 2 overloads have a best conversion
> f:\Work\prg\unnamed\include\0-utility\lang\foreach.h(281): could be 'foreach_detail::wrapper<boost::range_const_iterator<Range>::type> foreach_detail::begin(const Range &)'
> f:\Work\prg\unnamed\include\0-utility\lang\foreach.h(274): or 'foreach_detail::wrapper<boost::range_iterator<Range>::type> foreach_detail::begin(Range &)'
> while trying to match the argument list '(const std::list<_Ty,_Ax>)'
> with
> [
> _Ty=Phoenix::PBoundedObject,
> _Ax=std::allocator<Phoenix::PBoundedObject>
> ]

>
> не может выбрать из этих двух вариантов:
>
> template<class Range>
> wrapper<typename boost::range_iterator<Range>::type>
>     begin( Range& range )
> {
>     return boost::begin( range );
> }
> 
> template<class Range>
> wrapper<typename boost::range_const_iterator<Range>::type>
>     begin(Range const& range )
> {
>     return boost::begin( range );
> }
>

>
> компилировал такое:
>
> const list<PBoundedObject>& objects;
> foreach (const PBoundedObject& i, objects)
>


Ну это явно косяк 7.0, я когда писал ту реализацию и не расчитывал на совместимость с VC6/7.0.
А с вариантом WH надо разобраться — почему там stack corruption. Может оптимизатор чего не так наоптимизировал?
Как вариант лечения FOR_EACHевых проблем могу предложить попробовать BOOST_FOR_EACH от Eric Niebler, он развивается-сопровождается, последняя версия лежит здесь. Может заработает с VC7.0?

> Кстати я уже делал замечания по поводу этого foreach, но похоже не в этой ветке.

> В твоей реализации эта ошибка тоже присутствует:
>
>
> F>#define FOR_EACH( ElementDecl, Range )\
> F>    if( bool _fe_break = false ) {}\
> F>    else\
> F>    for( foreach_detail::holder const\
> F>              &_fe_current = foreach_detail::begin(Range)\
> F>            , &_fe_last    = foreach_detail::end(Range)\
>

> здесь нужно не
> F> ; _fe_current(Range) != _fe_last(Range) && (_fe_break = !_fe_break)\
> а
> F> ; (_fe_break = !_fe_break) && _fe_current(Range) != _fe_last(Range)\
>
>
> F>        ; ++_fe_current(Range)\
> F>    )\
> F>    for( ElementDecl = *_fe_current(Range); _fe_break; _fe_break = false )\
> F>// end macro
>

>
> а то на таком примере будет boom:
>
>
> foreach (int& i, obj->ints) {
> obj=NULL;
> break;
> }
>


Спасибо, помнится я видел такое замечание, но видимо забыл об этом когда писал последнюю версию.
Posted via RSDN NNTP Server 1.9
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[9]: No more ugly functors
От: Костя Ещенко Россия  
Дата: 15.01.05 09:16
Оценка:
Костя Ещенко wrote:

Сорри, BOOST_FOREACH здесь http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler
Posted via RSDN NNTP Server 1.9
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[10]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 15.01.05 10:51
Оценка:
Здравствуйте, Костя Ещенко, Вы писали:

КЕ>Костя Ещенко wrote:


КЕ>Сорри, BOOST_FOREACH здесь http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler


точно также глючит

спотыкается на таком коде:

template <class T>
inline common_ptr<T> BNamespace::Find(const string& name) const {
    BOOST_FOREACH (PEntity i, this->contents)
    // BOOST_FOREACH (const PEntity& i, this->contents) глючит точно также
        if (i->GetName()==name) {
            if (i->GetType()==T::Type)
                return static_pointer_cast<T>(i);
            else
                return NULL;
        }

    return NULL;
}


я так понимаю это как-то связано с тем, что метод является const.
но почему тогда вариант WolfHound нормально компилился?
... << RSDN@Home 1.1.3 stable >>
Re[11]: No more ugly functors
От: Костя Ещенко Россия  
Дата: 15.01.05 14:29
Оценка:
yxiie wrote:

> КЕ>Сорри, BOOST_FOREACH здесь http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler

>
> точно также глючит
>
> спотыкается на таком коде:
>
>
> template <class T>
> inline common_ptr<T> BNamespace::Find(const string& name) const {
> BOOST_FOREACH (PEntity i, this->contents)
> // BOOST_FOREACH (const PEntity& i, this->contents) глючит точно также
> if (i->GetName()==name) {
> if (i->GetType()==T::Type)
> return static_pointer_cast<T>(i);
> else
> return NULL;
> }
> 
> return NULL;
> }
>

>
> я так понимаю это как-то связано с тем, что метод является const.

Здесь http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/boost_foreach/portability.html написано что VC7.0 имеет второй (нижний) уровень совместимости с BOOST_FOREACH, что означает что он не сможет работать с контейнером-rvalue. Но this->contents является const lvalue, так что все должно работать. Напиши в gmane.comp.lib.boost.user о баге, может починят.

> но почему тогда вариант WolfHound нормально компилился?


Тот который с container_traits или без них?
Posted via RSDN NNTP Server 1.9
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[12]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 15.01.05 14:44
Оценка:
Здравствуйте, Костя Ещенко, Вы писали:

КЕ>Здесь http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/boost_foreach/portability.html написано что VC7.0 имеет второй (нижний) уровень совместимости с BOOST_FOREACH, что означает что он не сможет работать с контейнером-rvalue. Но this->contents является const lvalue, так что все должно работать.


да, я читал...

КЕ>Напиши в gmane.comp.lib.boost.user о баге, может починят.


эээ... а как это?

>> но почему тогда вариант WolfHound нормально компилился?


КЕ>Тот который с container_traits или без них?


тот который без. семерка ведь не поддерживает частичную специализацию.
... << RSDN@Home 1.1.3 stable >>
Re[13]: No more ugly functors
От: Костя Ещенко Россия  
Дата: 16.01.05 03:08
Оценка:
yxiie:

> КЕ>Здесь http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/boost_foreach/portability.html написано что VC7.0 имеет второй (нижний) уровень совместимости с BOOST_FOREACH, что означает что он не сможет работать с контейнером-rvalue. Но this->contents является const lvalue, так что все должно работать.

>
> да, я читал...
>
> КЕ>Напиши в gmane.comp.lib.boost.user о баге, может починят.
>
> эээ... а как это?

Вот полный урл группы news://news.gmane.org/gmane.comp.lib.boost.user , используешь любой news-клиент, например Outlook Express.

> >> но почему тогда вариант WolfHound нормально компилился?

>
> КЕ>Тот который с container_traits или без них?
>
> тот который без. семерка ведь не поддерживает частичную специализацию.

Этот вариант не пытается понять что за контейнер ему передали. Из-за этого ему плевать на константность, но он не может работать ни с чем кроме STL-like контейнеров.
Posted via RSDN NNTP Server 1.9
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[14]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 20.01.05 12:49
Оценка:
я запостил в boost-users — ошибку компиляции он исправил. но после запуска у его варианта тоже выскаквает stack around variable 'xxx' corrupted. причем даже там, где вариант WolfHound'a работал
... << RSDN@Home 1.1.3 stable >>
Re[2]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 20.01.05 15:32
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>1)Оптимизатор в VC++7.1 работает на отлично с ооочень маленьким минусом.

WH>2)Учитывая что
WH> а)Я уже и не помню когда мне был нужен break/continue
WH> б)А цикл с такой смешной нагрузкой я использовал еще раньше...
WH>Утверждаю к использованию в своих проектах.

ну и как? используешь ли?
хотелось бы услышать твои впечатления, а то у меня как раз один негатив.
... << RSDN@Home 1.1.3 stable >>
Re[3]: No more ugly functors
От: WolfHound  
Дата: 20.01.05 16:19
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>ну и как? используешь ли?

Y>хотелось бы услышать твои впечатления, а то у меня как раз один негатив.
Было пару раз. Вроде работает. Просто я сейчас на C# пишу... а там практически одни foreach'и...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: No more ugly functors
От: WolfHound  
Дата: 20.01.05 16:19
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Ну что за беда у меня с этими foreach

Y>вариант WolfHound'a время от времени выдает run-time check failure — stack around 'xxx' variable corrupted,
Y>у меня подозрения, что он пропускает больше прогонов цикла, чем нужно, а твой вариант
Может дело в
Y>даже не компилится VC 7.0
Просто я тлько на 7.1 это пробовал.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 20.01.05 17:58
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, yxiie, Вы писали:


Y>>ну и как? используешь ли?

Y>>хотелось бы услышать твои впечатления, а то у меня как раз один негатив.
WH>Было пару раз. Вроде работает. Просто я сейчас на C# пишу... а там практически одни foreach'и...

в том то и дело, что "вроде"
... << RSDN@Home 1.1.3 stable >>
Re[9]: No more ugly functors
От: yxiie Украина www.enkord.com
Дата: 20.01.05 17:58
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, yxiie, Вы писали:


Y>>Ну что за беда у меня с этими foreach

Y>>вариант WolfHound'a время от времени выдает run-time check failure — stack around 'xxx' variable corrupted,
Y>>у меня подозрения, что он пропускает больше прогонов цикла, чем нужно, а твой вариант
WH>Может дело в
Y>>даже не компилится VC 7.0
WH>Просто я тлько на 7.1 это пробовал.

черт его знает, а чего в нем особенного такого?
кстати BOOST_FOREACH точно также глючит. даже больше
... << RSDN@Home 1.1.3 stable >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.