Re[6]: Могу предложить альтернативу
От: MaximE Великобритания  
Дата: 11.11.03 10:05
Оценка:
Здравствуйте, lboss, Вы писали:

L>Тогда бы конструкции такого вида не работали бы:


L>
L>  void f(A & val);
  
L>...
L>  f(A());
L>


Такие конструкции и не должны работать.

Это мелкософтовские студии такое позволяют. Если отключить "language extensions" в семерке, то такую ерунду уже не получится написать.

Удалено избыточное цитирование. -- ПК.
Censored, — ПК.
Re[7]: Могу предложить альтернативу
От: lboss Россия  
Дата: 11.11.03 10:34
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Такие конструкции и не должны работать.


ME>Это мелкософтовские студии такое позволяют. Если отключить "language extensions" в семерке, то такую ерунду уже не получится написать.


Ну ладно — это в конечном случае не принципиально. С моей точки зрения тут всё нормально ибо "const" это просто модификатор — сути он не меняет. Я считаю что запись:

   f(A());


Намного удобней, чем:
   {
     A tmp;
     f(tmp);
   }
С уважением Вадим.
Re[7]: Могу предложить альтернативу
От: e-Xecutor Россия  
Дата: 11.11.03 12:21
Оценка:
Здравствуйте, folk, Вы писали:

F>Не уверен что правильно понял. Наше rvalue класс-типа может быть неявно преобразовано в lvalue?

Однако ты прав.
То бишь не может.
То бишь код неправильный
А товарищи cl 7.1 и icl 7.1 тоже неправы, а g++ рулит

Таки rvalue может инициализировать только константную ссылку.
А объект возвращаемый функцией by value является rvalue.
Но! От него позволяется вызвать метод.
А если этот метод вернёт ссылку на него самого, то ею можно будет инициализировать
неконстантную ссылку
Re[8]: Могу предложить альтернативу
От: e-Xecutor Россия  
Дата: 11.11.03 12:28
Оценка:
EX>Но! От него позволяется вызвать метод.
EX>А если этот метод вернёт ссылку на него самого, то ею можно будет инициализировать
EX>неконстантную ссылку
Не, нельзя так делать, темпоральный объект помрёт
Re[3]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 14:32
Оценка:
Здравствуйте, Шахтер, Вы писали:

ЮБ>>
 ЮБ>> struct miner {
 ЮБ>>    int * data_;
 ЮБ>>    size_t i_;
 ЮБ>>    miner(int * data) : data_(data), i_(0) { data_[0] = data_[1] = 1; }
 ЮБ>>    int operator()(int) {
 ЮБ>>        if (i_ < 2)
 ЮБ>>            return ++i_, 1;
 ЮБ>>        return data_[i_-1] + data_[i_++ -2];
 ЮБ>>    }
 ЮБ>> };
 ЮБ>>
 ЮБ>> int main(int argc, char* argv[])
 ЮБ>> {
 ЮБ>>    int d[10] = {0};
 ЮБ>>    std::copy(d, std::transform(d, d+10, d, miner(d)),
 ЮБ>>      std::ostream_iterator<int>(std::cout, "\n")); // имхо так красивше
 ЮБ>>    return 0;
 ЮБ>> }
 ЮБ>>


Ш> В этом коде насколько оправдан вызов transform. Дело в том, что он читает

Ш> данные из того же массива, в который пишет.

Ничего страшного, более того, это явно разрешается стандартом:

25.2.3/5 Notes: result may be equal to first in case of unary transform,
or to first1 or first2in case of binary transform.


Ш> Стандарт вроде не определяет, в каком точно порядке transform работает.


Это определяется требованиями к алгоритму поддерживать работу с InputIterator.
Работа с InputIterator автоматически означает движение от начала к концу.

Ш> Может он откладывает запись, например.


Я не представляю, как это возможно сделать для OutputIterator, учитывая что
алгоритм не может возвращаться и копия OutputIterator не пригодна ни для
инкремента, ни для записи (*a = t) после того, как оригинал инкрементирован,
и наоборот.

Ш> Или вообще едет сверху вниз (это конечно маловероятно, но возможно).


Это невозможно: InputIterator не позволяет двигаться от конца к началу.

Ш> Или запускает несколько потоков на многопроцессорной системе.


Я не представляю, как это возможно сделать для InputIterator, учитывая что
алгоритм не может возвращаться и копия InputIterator не пригодна ни для
инкремента, ни для разыменования после того, как оригинал инкрементирован,
и наоборот.

Ш> Requires: op and binary_op shall not have any side effects.

Ш> Что эта фраза означает?

1.9/7 Accessing an object designated by a volatile lvalue (3.10),
modifying an object, calling a library I/O function, or calling a function
that does any of those operations are all side effects, which are changes
in the state of the execution environment.


Соответстенно, ничего из перечисленного op или binary_op делать не должны
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Крокодилы в клетке
От: Аноним  
Дата: 11.11.03 14:49
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Ш>> Requires: op and binary_op shall not have any side effects.

Ш>> Что эта фраза означает?

ПК>

1.9/7 Accessing an object designated by a volatile lvalue (3.10),
ПК>modifying an object, calling a library I/O function, or calling a function
ПК>that does any of those operations are all side effects, which are changes
ПК>in the state of the execution environment.


ПК>Соответстенно, ничего из перечисленного op или binary_op делать не должны


Т.е. изменять свое внутреннее состояние они не могут?
Re[5]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 15:03
Оценка:
Здравствуйте, , Вы писали:

Ш>>> Requires: op and binary_op shall not have any side effects.

Ш>>> Что эта фраза означает?

ПК>> <...>


> Т.е. изменять свое внутреннее состояние они не могут?


Не могут. Например, гарантий, что функтор не будет копироваться, нет.
В этом аспекте приведенный код формально неверен. Правда, сомневаюсь,
что на практике хотя бы одна реализация стандартной библиотеки не будет
работать с данным функтором.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Крокодилы в клетке
От: Юнусов Булат Россия  
Дата: 11.11.03 15:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:


ПК>Не могут. Например, гарантий, что функтор не будет копироваться, нет.

ПК>В этом аспекте приведенный код формально неверен. Правда, сомневаюсь,
ПК>что на практике хотя бы одна реализация стандартной библиотеки не будет
ПК>работать с данным функтором.

Да, для правильности (тот же Мейерс Effective STL), надо было конструктор копирования приписать, поленился, там еще и проверок нет скажем на нульность агрумента конструктора и на выход за границы массива.
Re[7]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 15:58
Оценка:
Здравствуйте, Юнусов, Вы писали:

ПК>> Не могут. Например, гарантий, что функтор не будет копироваться, нет.


ЮБ> Да, для правильности (тот же Мейерс Effective STL), надо было конструктор

ЮБ> копирования приписать

А как бы он помог в данном случае, если бы для одной части диапазона
использовалась одна копия, а для другой — другая?
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[8]: Крокодилы в клетке
От: Юнусов Булат Россия  
Дата: 11.11.03 16:32
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>А как бы он помог в данном случае, если бы для одной части диапазона

ПК>использовалась одна копия, а для другой — другая?

А как такое может случится?
Re[9]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 16:45
Оценка:
Здравствуйте, Юнусов, Вы писали:

ПК>> А как бы он помог в данном случае, если бы для одной части диапазона

ПК>> использовалась одна копия, а для другой — другая?

ЮБ> А как такое может случится?


Я тоже очень сомневаюсь в практической осуществимости подобного, но формально
ничто в стандарте не запрещает реализации сделать такую гадость Собственно,
я полагаю, что авторы стандарта, решив не тратить усилия на формулировки того,
какие именно побочные эффекты запрещены, на всякий случай перестраховались,
добавив требование отсутствия любых.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[10]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 17:27
Оценка: 10 (1)
Здравствуйте, Павел, Вы писали:

ПК> Собственно, я полагаю, что авторы стандарта, решив не тратить усилия

ПК> на формулировки того, какие именно побочные эффекты запрещены,
ПК> на всякий случай перестраховались, добавив требование отсутствия любых.

Ага... Дальнейшее разбирательство показало, что имеется library defect report
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#242 , который как
раз касается побочных эффектов стандартных алгоритмов, включая и std::transform.
Текущее предложение относительно побочных эффектов std::transform выглядит так:

Requires: op and binary_op shall not invalidate iterators or subranges, or modify
elements in the ranges [first1, last1], [first2, first2 + (last1 — first1)],
and [result, result + (last1 -first1)].
[Footnote: The use of fully closed ranges is intentional --end footnote]

Соответственно, наши нынешние практические ожидания подтверждаются дальнейшими
изысканиями формалистов-стандартизаторов
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Крокодилы в клетке
От: Юнусов Булат Россия  
Дата: 11.11.03 18:06
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>

Requires: op and binary_op shall not invalidate iterators or subranges, or modify
ПК>elements in the ranges [first1, last1], [first2, first2 + (last1 — first1)],
ПК>and [result, result + (last1 -first1)].
ПК>[Footnote: The use of fully closed ranges is intentional --end footnote]

ПК>Соответственно, наши нынешние практические ожидания подтверждаются дальнейшими
ПК>изысканиями формалистов-стандартизаторов

значит выделенный код будет считатся неверным
    miner(int * data) : data_(data), i_(0) { data_[0] = data_[1] = 1; }

он правда там и так лишний по большому счету
Re[12]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 11.11.03 20:25
Оценка:
Здравствуйте, Юнусов Булат, Вы писали:

ПК>>

Requires: op and binary_op shall not invalidate iterators or subranges, or modify
ПК>>elements in the ranges [first1, last1], [first2, first2 + (last1 — first1)],
ПК>>and [result, result + (last1 -first1)].
ПК>>[Footnote: The use of fully closed ranges is intentional --end footnote]


ЮБ>значит выделенный код будет считатся неверным

ЮБ>
ЮБ>    miner(int * data) : data_(data), i_(0) { data_[0] = data_[1] = 1; } 
ЮБ>

ЮБ>он правда там и так лишний по большому счету

С этим кодом и было, и будет все в порядке: конструирование функтора никак не взаимодействует с дальнейшим выполнением std::transform. В процитированном фрагменте речь шла о побочных эффектах внутри operator(). В текущей редакции стандарта запрещены любые побочные эффекты, в том числе и модификация данных-членов функтора. Предложенное исправление, вошедшее в текущий черновик, данное — имхо, чисто теоретическое — ограничение снимает.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Могу предложить альтернативу
От: folk Россия  
Дата: 11.11.03 22:47
Оценка:
Здравствуйте, lboss, Вы писали:

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


F>>И на это есть ответ

F>>Я рассматривал подобный монолитный вариант, но мне подумалось что я смогу повторно использовать элементарные wrap/unwrap для другой задачи, так что в результате сделал на них и поместил их в namespace util (а не в _foreach как в опубликованном варианте).

L>Не понял аргументации — ибо для практически любой другой задачи проще итераторами пользоваться всё-таки... по моему...


Тоже не понял... Что есть практически любая задача? Я совершенно не имел ввиду итераторы/контейнеры...

F>>А вообще это правильно, чем больше удается вынести из мароса в шаблон, тем лучше. В скопе цикла находятся меньше скрытых макросом переменных.


L>Вообще-то, по моему, главный принцип (или заслуга) данного подхода — это работающий break, и ясность реализации...


Ну с break то все давно решено. А насчет ясности ты наверное прав.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[4]: Крокодилы в клетке
От: Шахтер Интернет  
Дата: 12.11.03 00:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Ш>> В этом коде насколько оправдан вызов transform. Дело в том, что он читает

Ш>> данные из того же массива, в который пишет.

ПК>Ничего страшного, более того, это явно разрешается стандартом:

ПК>

ПК>25.2.3/5 Notes: result may be equal to first in case of unary transform,
ПК>or to first1 or first2in case of binary transform.


Ш>> Стандарт вроде не определяет, в каком точно порядке transform работает.


ПК>Это определяется требованиями к алгоритму поддерживать работу с InputIterator.

ПК>Работа с InputIterator автоматически означает движение от начала к концу.

Здесь не всё так просто. И вот почему. Реализация библиотеки может предоставлять специализации алгоритма для различных типов функторов. Более того, насколько я понимаю, это и делается (нужно посмотреть исходники, сейчас у меня на это просто нет времени). В этом коде итераторы -- это указатели, значит, для них те трюки, которые я описал, вполне возможны. Стандарт, насколько я понимаю, всё-таки не определяет точно порядок выполнения преобразований. Он определяет только что будет аргументом, и куда кладутся результаты преобразований. Для ясности, есть две последовательности x1,...,xn y1,...,yn. transform делает последовательность преобразований y1=f(x1),...,yn=f(xn). Но вот порядок, на самом деле, явно не продекларирован. Т.е. может быть и
yn=f(xn),...,y1=f(x1). Или ещё как-то. В данном же конкретно случае этот порядок принципиально важен -- иначе не будет работать. Замечание, приведённое выше, не по существу, т.к. оно верно, если нет связи между последовательностью операций, в нашем же случае такая связь есть. У нас же вычисление рекурсивной последовательности.
Между прочим, не так уж сложно написать библиотечку извращённых реализаций алгоритмов. Она может оказать неоценимую помощь при ловле вот таких тонких ситуаций.
... << RSDN@Home 1.1 beta 2 >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Крокодилы в клетке
От: Павел Кузнецов  
Дата: 12.11.03 09:43
Оценка:
Здравствуйте, Шахтер, Вы писали:

ПК>> Это определяется требованиями к алгоритму поддерживать работу с InputIterator.

ПК>> Работа с InputIterator автоматически означает движение от начала к концу.

Ш> Здесь не всё так просто. И вот почему. Реализация библиотеки может

Ш> предоставлять специализации алгоритма для различных типов функторов.

Теоретически — возможно. Практически — не представляю, зачем нужна специализация
std::transform, скажем, для random access iterators. Разве что специально для того,
чтобы "навернуть" функционал Юнуса Булатова Формально, ты, конечно, прав.

Ш> Стандарт, насколько я понимаю, всё-таки не определяет точно порядок выполнения

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

Для некоторых алгоритмов определяет (например, std::for_each).
Но, вообще, по этому поводу тоже defect report имеется, и даже не один:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#92
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#290

Даже конкретно по поводу порядка в std::transform есть:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#293

Ш> В данном же конкретно случае этот порядок принципиально важен -- иначе не будет

Ш> работать. Замечание, приведённое выше, не по существу, т.к. оно верно, если нет
Ш> связи между последовательностью операций, в нашем же случае такая связь есть.

Согласен. В принципе, имхо, более удачным решением в данном случае было бы
использование, например, std::for_each.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: No more ugly functors
От: Аноним  
Дата: 12.11.03 11:43
Оценка:
Здравствуйте, folk, Вы писали:

F>Навеяно словами WolfHound'a в ветке C++/CLI PDC presentation
Автор: alexkro
Дата: 01.11.03

F>Вот создал макрос для перебора всех элементов контейнера, стараясь как можно больше приблизиться к
F>приведенному там синтаксису.
F>В результате организация цикла выглядит примерно так: FOR_EACH(int& i, the_container)

А можно ли данный FOR_EACH с std::map использовать ?
Re: No more ugly functors
От: Аноним  
Дата: 12.11.03 12:26
Оценка:
Здравствуйте, folk, Вы писали:

F>#define FOR_EACH_(Decl, First, Last) \

F>if (false) {} else /*VC6 for-init-scope bug workaround*/ \

А что это за баг такой и зачем здесь его надо обходить ?
Re[2]: No more ugly functors
От: jazzer Россия Skype: enerjazzer
Дата: 12.11.03 12:52
Оценка:
Здравствуйте, Аноним, Вы писали:

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


F>>#define FOR_EACH_(Decl, First, Last) \

F>>if (false) {} else /*VC6 for-init-scope bug workaround*/ \

А>А что это за баг такой и зачем здесь его надо обходить ?


баг в том, что в for(int i;); i видна после цикла, а по Стандарту она должна быть видна только внутри цикла
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.