Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
1

Ленивые вычисления

03.07.2013, 10:25. Показов 10657. Ответов 27

Author24 — интернет-сервис помощи студентам
____Много есть информации под boost, так же не отстает шарп и опережает всех хаскель. В плюсах только со стандарта C++0x. Даже попалась цельная Qt-шная библиотека для этого дела. Вообще концепция ленивых вычислений зародилась для функциональных языков. Но это все придумано, если возвращаться к C++, для удобства оперирования функторами и еще каких-то таинств. Но по сути же простые "ленивые вычисления" доступны во многих языках, компиляторы которых действуют по некоему принципу call by value. То есть когда значение получено, дальше его обсчитывать смысла нет. Если первый операнд операции && ложен, то вычислять следующие не нужно.
____Общий смысл "ленивых вычислений" в том, что экономится время на проведении вычислений, результаты которых заведомо не будут использованы в дальнейшем программой. Соответственно, за счет снижения объемов вычислений повышается и производительность программы, а за счет отсутствия необходимости хранить в памяти результаты вычислений снижаются и требования программы к памяти. Помимо этого, ленивые вычисления избавляют программиста от необходимости следить за тем, какие именно вычисления будут в дальнейшем востребованы программой, а какие, напротив, окажутся совершенно бесполезными. Последнее не всегда хорошо, учитывая опять же гибкость плюсов, в которых компилятор не даст, вопреки обычному подходу, поступать как заблагорассудится программисту. Но на то в принципе и расчет.

Принцип "ленивого вычисления" проще всего рассмотреть на следующем примере:
C++
1
if (A && B && C && D) {...}
C++
1
2
3
4
5
6
7
8
9
if (A) {
  if (B) {
    if (C) {
      if (D) {
        ...
      }
    }
  }
}
В первом случае не понятно, что, если A ложно, то и остальные вычисления происходить не будут. Во-втором же наглядно видно, что, при ложном A, тело первого оператора условия не будет выполнено.
Оба приведенных кода делают одно и то же. Отличие лишь в компромиссе между читабельностью кода и его объемом.
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2013, 10:25
Ответы с готовыми решениями:

Ленивые вычисления в C++
Как переопределить операторы так, чтобы можно было запомнить формулу, чтобы вычислить её по...

Получение i-ого элемента массива без вычисления всех элементов (Ленивые вычисления)
Здравствуйте! Необходимо в цикле получать каждый i-й элемнент. Работаю с массивами массивов целых...

Ленивые вычисления
Добрый вечер, Уважаемые форумчане! Есть вот такое задание: С помощью класса Stream опишите...

Ленивые вычисления или "я что-то пропустил и в c# есть ссылки на строки?"
Доброго дня, уважаемые члены форума! Прошу знающих людей подсказать верный путь к решению такой...

27
Модератор
Эксперт по электронике
8902 / 6672 / 917
Регистрация: 14.02.2011
Сообщений: 23,500
03.07.2013, 10:31 2
можно добавить еще такую конструкцию
C++
1
2
3
4
if(A|| B ||C)
{
......
}
равно

C++
1
2
3
4
5
6
if(!A)
 if(!B)
  if(!C)
   {
    .......
    }
1
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 10:37 3
Цитата Сообщение от SatanaXIII Посмотреть сообщение
В плюсах только со стандарта C++0x.
Не понял, Вы хотите сказать, что "ленивость" появилась в плюсах только начиная с C++0x?

Добавлено через 2 минуты
Цитата Сообщение от SatanaXIII Посмотреть сообщение
В первом случае не понятно, что, если A ложно, то и остальные вычисления происходить не будут.
Смотря чем являются эти A,B,C,D
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 10:41 4
SatanaXIII, и в чем же вопрос?
0
Модератор
Эксперт по электронике
8902 / 6672 / 917
Регистрация: 14.02.2011
Сообщений: 23,500
03.07.2013, 10:42 5
Цитата Сообщение от ValeryS Посмотреть сообщение
можно добавить еще такую конструкцию
соврал ведь я думал о порядке вычисления а про условие не подумал
вот так должно выглядеть
C++
1
2
3
4
if(A || B || C)
{
// что то делаем 
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if(A)
 {
  // что то делаем 
 }
 else
{
   if(B)
  {
   // что то делаем 
  }
  else
   {
    if(C)
    {
     // что то делаем 
     } 
   }
 }
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 10:45 6
Цитата Сообщение от Croessmah Посмотреть сообщение
Смотря чем являются эти A,B,C,D
чем бы не являлись §5.14/1:
The && operator groups left-to-right. The operands are both contextually converted to type bool (Clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
1
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
03.07.2013, 10:49  [ТС] 7
Цитата Сообщение от Croessmah Посмотреть сообщение
Не понял, Вы хотите сказать, что "ленивость" появилась в плюсах только начиная с C++0x?
Не совсем:
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Но это все придумано, если возвращаться к C++, для удобства оперирования функторами и еще каких-то таинств
Честно сказать, я тут не до конца разобрался.

Цитата Сообщение от Croessmah Посмотреть сообщение
Смотря чем являются эти A,B,C,D
Положим функциями:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bool A(){cout << " A "; return true;}
bool B(){cout << " B "; return false;}
bool C(){cout << " C "; return false;}
bool D(){cout << " D "; return false;}
 
 
int main(int argc, char* argv[])
{
 
if (A() && B() && C() && D())
  {cout << "done";}
 
 
 
if (A())
  {
  if (B())
  {
    if (C())
    {
      if (D())
      {
        cout << "done";
      }
    }
  }
}
Добавлено через 46 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
и в чем же вопрос?
Да ни в чем. ) Хочется обсудить. Все верно описно?
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 10:54 8
Цитата Сообщение от Tulosba Посмотреть сообщение
чем бы не являлись §5.14/1:
Если в классе перегружены логические операторы, то их ленивость теряется, ибо это уже не совсем операторы
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 11:41 9
Цитата Сообщение от Croessmah Посмотреть сообщение
Если в классе перегружены логические операторы, то их ленивость теряется, ибо это уже не совсем операторы
show me example

Добавлено через 24 минуты
Собственно, сам родил:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
 
class A
{
public:
    A( int a ) : a(a) { }
    A operator&&( const A& a )
    {
        std::cout << "operator &&" << std::endl;
        return *this;
    } 
    
    operator bool()
    {
        std::cout << "operator bool : " << a << std::endl;
        return false;
    }
    
    A& operator()() 
    { 
        std::cout << "operator () : " << a << std::endl;
        return *this; 
    }
private:
    const int a;
};
 
int main() {
    
    A a1(1), a2(2), a3(3);
    
    if( a1() && a2() && a3() )
    {
        
    }
    
    return 0;
}
https://ideone.com/YdbmM6

Если убрать operator&& из класса, то operator() вызовется только для a1.
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 11:53 10
Цитата Сообщение от Tulosba Посмотреть сообщение
The && operator groups left-to-right
Наверное, одним из самых важных аргументов будет то, что эти операторы являются
Цитата Сообщение от Tulosba Посмотреть сообщение
groups left-to-right
тогда как operator||уже таким не будет.
Для примера, вот просто, банально и бездарно:
http://ideone.com/R1p7Oo
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 12:02 11
Цитата Сообщение от Croessmah Посмотреть сообщение
Для примера, вот просто, банально и бездарно:
http://ideone.com/R1p7Oo
Не очень понял, что показывает этот пример. Тут ведь если убрать из класса operator||, то даже не скомпилируется.
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 12:04 12
Цитата Сообщение от Tulosba Посмотреть сообщение
Не очень понял, что показывает этот пример
Выражение в условии:
C++
1
(a || *a)
а выполнение:
operator*
operator||(A,A)
то есть уже имеем не left-to-right порядок, который можно предположить при чтении кода
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 12:22 13
Цитата Сообщение от Croessmah Посмотреть сообщение
то есть уже имеем не left-to-right порядок,
Это уже получается порядок вычисления аргументов функции, а он, как известно, в стандарте не регламентирован.
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 12:25 14
Цитата Сообщение от Tulosba Посмотреть сообщение
Это уже получается порядок вычисления аргументов функции, а он, как известно, в стандарте не регламентирован.
вообще, наверное, лучше перегрузить void*, вместо всех этих логических операторов, в т.ч. преобразование к bool
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 12:32 15
Цитата Сообщение от Croessmah Посмотреть сообщение
вообще, наверное, лучше перегрузить void*, вместо всех этих логических операторов, в т.ч. преобразование к bool
какой профит?
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 13:05 16
Tulosba, из-за перегрузки преобразования bool иногда могут возникнуть неприятные касты
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 13:59 17
Croessmah, а что если http://en.wikibooks.org/wiki/M... /Safe_bool ?
1
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 18:03 18
Цитата Сообщение от Tulosba Посмотреть сообщение
Croessmah, а что если http://en.wikibooks.org/wiki/M... /Safe_bool ?
а зачем? Лишнийе геморрой проблемы себе на голову
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2013, 18:27 19
Цитата Сообщение от Croessmah Посмотреть сообщение
а зачем?
я про C++11 версию в частности (explicit bool)
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.07.2013, 18:31 20
Цитата Сообщение от Tulosba Посмотреть сообщение
я про C++11 версию в частности (explicit bool)
Не заметил Чтобы не говорили, но в 11 стандарте появилось много плюшек. Ждем рефлексию
0
03.07.2013, 18:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.07.2013, 18:31
Помогаю со студенческими работами здесь

Ленивые работники и что с этим делать
Всем добрый день. Будучи эникеем в небольшой конторе, столкнулся с таким явлением: Какая ни будь...

Напишите программу вычисления суммы: 1! + 2! + 3! + … + n!, используя функцию вычисления факториала числа k
Напишите программу вычисления суммы: 1! + 2! + 3! + … + n!, используя функцию вычисления факториала...

Напишите программу вычисления суммы: 1! + 2! + 3! + … + n!, используя функцию вычисления факториала числа k.
Напишите программу вычисления суммы: 1! + 2! + 3! + … + n!, используя функцию вычисления факториала...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru