Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите написать пару макросов 
:(
    Опции темы
newbee
Дата 3.2.2012, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Здравствуйте, мои дорогие плюсисты smile

Как известно, операторы AND и OR возвращают boolean. Но это совершенно не вяжется с моим чувством прекрасного! Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления. Аналогично с OR: последовательно вычисляются выражения и возвращается результат первого истинного. Естественно OR и AND должны быть ленивыми.

Надеюсь, всем здесь присутствующим очевидно, что AND и OR, если отбросить синтаксическую шелуху, являются разновидностью условного оператора, к примеру
Код

one AND two AND three ->
if(one)
 if(two)
  if(three)


В С++ условный оператор if-then-else не возвращает значения, зато есть ?: который подходит с существенным ограничением: типы всех выражений должны совпадать или быть приводимыми.

Вторая проблема, с которой я столкнулась, - это рекурсивные макросы, которых в С++ нет, но с помощью внешнего генератора можно эмулировать.

И вот я сейчас сижу и думаю как написать правильный AND-OR. Идеально синтаксически и семантически это должно выглядеть примерно так:
Код

std::cout<<$AND(myobject, 2, 3-5, string.indexOf('q')!=42, "hello")<<std::endl; => "hello"(pass) | false (fail)
object *o=$AND(object_registered(another)) => another | nil
//object_registered(another) => another | nil
object *o=$(OR object1 object2 object3) => first of non-nil object | nil


Интересно, возможно ли реализовать такое и насколько близко к тому, что я хочу... Макросы, шаблоны, неоптимало и тормозно - все пофигу, лишь бы заработало. Есть ли у кого какие соображения?


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 3.2.2012, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



newbee, жуткий пример %)
ты таки на лиспе пишешь?
покажи псевдокодом что хочешь получить в итоге?

зы
boost можно использовать?

Добавлено через 5 минут
Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
one AND two AND three ->
if(one)
 if(two)
  if(three)

это понятно. не понял что должно (хочешь) получить в итоге.

Добавлено через 7 минут и 29 секунд
Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
std::cout<<$AND(myobject, 2, 3-5, string.indexOf('q')!=42, "hello")<<std::endl; => "hello"(pass) | false (fail)

это расшифруй.

Добавлено через 11 минут и 2 секунды
Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
=> "hello"(pass) | false (fail)

т.е. результатом того что выше, может быть либо "hello(pass)", либо "false (fail)" ? но опять же, не понятно назначение и способ вычисления переменных в $AND(...)

Добавлено через 14 минут и 21 секунду
Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления. Аналогично с OR: последовательно вычисляются выражения и возвращается результат первого истинного. Естественно OR и AND должны быть ленивыми.

кажись понял.. но возвращаться же будет bool, а в твоем примере "hello" %)
PM WWW   Вверх
newbee
Дата 3.2.2012, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Код
покажи псевдокодом что хочешь получить в итоге?
Ну я выше уже пыталась))

Давай другой... Пусть у нас будут объекты типа object_t, они составляют иерархическую структуру (есть родители и дети) и все они где-нибудь зарегистрированы...

Код

object_t *o1, *o2;
...
object_t *res=$OR(o1, find_object("Object"), $AND(o2, o2->parent()), make_default_object());

//Это выражение читается так:
object_t *res=0;
if(o1)
 res=o1;
 else{
  if(object_t *tmp=find_object("Object"))
   res=tmp;
   else{
    if(o2 && o2->parent()!=0)
     res=o2->parent();
     else{
      res=make_default_object();
     }
   }
 }


Цитата(boostcoder @  3.2.2012,  17:12 Найти цитируемый пост)

зы
boost можно использовать? 
Можно. А если это потом можно будет повторить без него (сделать примитивные аналоги), вообще счастье будет smile

Я на концерт убегаю, вечером вернусь! ))


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 3.2.2012, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  3.2.2012,  16:29 Найти цитируемый пост)
Я на концерт убегаю

 smile 
оторвись, как следует.
PM WWW   Вверх
newbee
Дата 3.2.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(boostcoder @  3.2.2012,  17:12 Найти цитируемый пост)
результатом того что выше, может быть либо "hello(pass)", либо "false (fail)"
В случае успеха - "hello", в случае неудачи - false.

Цитата(boostcoder @  3.2.2012,  17:12 Найти цитируемый пост)
кажись понял.. но возвращаться же будет bool, а в твоем примере "hello" %) 
 ?: возвращает сам объект. Но там тоже с ограничением по типам, я выше писала.

ЗЫЫЫ Сорри за плохой пример в ОП, постаралась нормальный придумать ))


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 3.2.2012, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ага. понял.

над решением нужно подумать...
PM WWW   Вверх
newbee
Дата 3.2.2012, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



И наверное я погорячилась, с "hello" и false, давай считать, что внутри результаты выражений однотипны. Как в последнем примере.


--------------------
You're face to face
With man who sold the world
PM   Вверх
tzirechnoy
Дата 3.2.2012, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 2
Всего: 16



Шли бы Вы хаскель изучать, а? Тем более, что через монады это действительно делается, в том числе и в плюсах.
PM MAIL   Вверх
boostcoder
Дата 3.2.2012, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  3.2.2012,  16:35 Найти цитируемый пост)
давай считать, что внутри результаты выражений однотипны. 

ок.

сегодня постараюсь закончить.. реализация на boost.preprocessor.
PM WWW   Вверх
borisbn
Дата 3.2.2012, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



А что должен возвращать AND, если одно из выражений ложно ?
В случае с bool или с указателем - понятно (false и NULL соответственно), а что в случае с int или с пользовательским типом ?

Код

struct MyObject {
    MyObject( bool trueOrFalse ) : m_trueOrFalse;
    operator bool() const { return m_trueOrFalse; }
    bool m_trueOrFalse;
};
MyObject o1( true ), o2( false );
MyObject res = AND( o1, o2 );


М.б. то выражение, на котором "споткнулся" ??? В данном случае o2 ?

А как быть, если все выражения в OR - ложны ?
Код

MyObject o1( false ), o2( false );
MyObject res = OR( o1, o2 );


В общем, надо бы ТЗ поточнее выдать )))


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 3.2.2012, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  3.2.2012,  18:26 Найти цитируемый пост)
А что должен возвращать AND, если одно из выражений ложно ?


Цитата(borisbn @  3.2.2012,  18:26 Найти цитируемый пост)
А как быть, если все выражения в OR - ложны ?

я так понял - исключение выбрасывать.
PM WWW   Вверх
502
Дата 3.2.2012, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Я всегда прав
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 16.7.2011

Репутация: нет
Всего: 4



Цитата(borisbn @  3.2.2012,  18:26 Найти цитируемый пост)
А что должен возвращать AND, если одно из выражений ложно ?

Цитата(borisbn @  3.2.2012,  18:26 Найти цитируемый пост)
М.б. то выражение, на котором "споткнулся" ???

 smile 


Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления. Аналогично с OR: последовательно вычисляются выражения и возвращается результат первого истинного. Естественно OR и AND должны быть ленивыми.

это все есть в javascript
Код

(4 && 5) + 4 //=> 9
(5 && 4!=4) //=> false
(5 && 0) //=> 0


Это сообщение отредактировал(а) 502 - 3.2.2012, 18:37
PM MAIL   Вверх
borisbn
Дата 3.2.2012, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(502 @  3.2.2012,  18:34 Найти цитируемый пост)
А что должен возвращать AND, если одно из выражений ложно ?

false

дык
Цитата(borisbn @  3.2.2012,  18:26 Найти цитируемый пост)
В случае с bool или с указателем - понятно (false и NULL соответственно), а что в случае с int или с пользовательским типом ?


это ж не простой AND и OR...

Цитата(502 @  3.2.2012,  18:34 Найти цитируемый пост)
это все есть в javascript

переменные в javascript не типизированны, а в Си++ ты не можешь в зависимости от условия присвоить переменной либо false либо std::string, например.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 3.2.2012, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Примерно так:
Код

// При необходимости прикрутить шаблоны
typedef void* T;
T temp_push(T);
T temp_pop();
#define AND(a,b) (temp_push(a)?temp_pop(),(b):(temp_pop(),))
#define OR(a,b) (temp_push(a)?temp_pop():(temp_pop(),(b)))


PM   Вверх
502
Дата 3.2.2012, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Я всегда прав
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 16.7.2011

Репутация: нет
Всего: 4



Цитата(borisbn @  3.2.2012,  18:38 Найти цитируемый пост)
дык

я поторопился, не false
Цитата(borisbn @  3.2.2012,  18:38 Найти цитируемый пост)
переменные в javascript не типизированны

вроде в c++ есть auto, или нет?
PM MAIL   Вверх
borisbn
Дата 3.2.2012, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(502 @  3.2.2012,  18:40 Найти цитируемый пост)
вроде в c++ есть auto, или нет?

если на этапе компиляции тип возвращаемого значения у выражения понятен компилятору, то он вместо auto подставляет этот тип. если же компилятор не может определить тип (а в твоём случае он определяется на этапе выполнения), то компилятор выдаст ошибку на auto.
Код

std::vector< int > v;
auto it = v.begin(); // тип it будет std::vector< int >::iterator

std::string str = "true";
bool b = false;
auto x = ... ? str : b; // error



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 3.2.2012, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления.

а если ни одно не истинно, что возвращать?

Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
OR: последовательно вычисляются выражения и возвращается результат первого истинного.

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

Это сообщение отредактировал(а) boostcoder - 3.2.2012, 19:38
PM WWW   Вверх
boostcoder
Дата 3.2.2012, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вот что получилось:
Код

#include <iostream>
#include <boost/preprocessor.hpp>

#define Ext_OR_SUBCOND(unused, idx, seq) \
   (BOOST_PP_SEQ_ELEM(idx, seq)) \
   ? \
   (BOOST_PP_SEQ_ELEM(idx, seq)) \
   :

#define Ext_OR(seq, def) \
   ( \
      BOOST_PP_REPEAT( \
         BOOST_PP_SEQ_SIZE(seq), \
         Ext_OR_SUBCOND, \
         seq \
      ) \
      (def) \
   )

#define Ext_AND_SUBCOND(unused, idx, tuple) \
   !( \
      BOOST_PP_SEQ_ELEM( \
         idx, \
         BOOST_PP_TUPLE_ELEM(2, 0, tuple) \
      ) \
   ) ? ( \
      BOOST_PP_IF( \
         BOOST_PP_EQUAL(idx, 0), \
         BOOST_PP_TUPLE_ELEM(2, 1, tuple), \
         BOOST_PP_SEQ_ELEM( \
            BOOST_PP_SUB(idx, 1), \
            BOOST_PP_TUPLE_ELEM(2, 0, tuple) \
         ) \
      ) \
   ) :

#define Ext_AND(seq, def) \
   ( \
      BOOST_PP_REPEAT( \
         BOOST_PP_SEQ_SIZE(seq), \
         Ext_AND_SUBCOND, \
         (seq,def) \
      ) \
      ( \
         BOOST_PP_SEQ_ELEM( \
            BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
            seq \
         ) \
      ) \
   )

int def() {
   return -1;
}

int main() {
   int b1=1, b2=2, b3=3;

   std::cout << Ext_OR((b1)(b2)(b3), def()) << std::endl; // 1
   std::cout << Ext_AND((b1)(b2)(b3), def()) << std::endl; // 3
}

http://liveworkspace.org/code/f72ac6a3004d...60bd21374ab273d

результат препроцессирования:
Код

int def() {
   return -1;
}

int main() {
   int b1=1, b2=2, b3=3, b4=0;

   std::cout << ( ( b1 ) ? ( b1 ) : ( b2 ) ? ( b2 ) : ( b3 ) ? ( b3 ) : (def()) ) << std::endl;
   std::cout << ( !( b1 ) ? ( def() ) : !( b2 ) ? ( b1 ) : !( b3 ) ? ( b2 ) : ( b3 ) ) << std::endl;
}



т.к. не известно как поступать если ни одно из условий не верно, в макросы Ext_OR и Ext_AND добавил второй аргумент принимающий выражение.

Это сообщение отредактировал(а) boostcoder - 3.2.2012, 21:51
PM WWW   Вверх
newbee
Дата 3.2.2012, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(borisbn @  3.2.2012,  19:26 Найти цитируемый пост)
А что должен возвращать AND, если одно из выражений ложно ?
В случае с bool или с указателем - понятно (false и NULL соответственно), а что в случае с int или с пользовательским типом ?
Конструктор по умолчанию.

Цитата(tzirechnoy @  3.2.2012,  18:25 Найти цитируемый пост)
Шли бы Вы хаскель изучать, а? Тем более, что через монады это действительно делается, в том числе и в плюсах. 
Ну вот зачем ты глупую девушку грузишь такими высокими материями, монады, каррирование, паттерн матчинг... Может мне еще матфаковский курс матана вызубрить и теорию категорий? Если напишешь свой вариант с монадами и замыканиями или дашь ссылки на решение моей задачки, будем разговаривать...

Цитата(borisbn @  3.2.2012,  19:26 Найти цитируемый пост)
М.б. то выражение, на котором "споткнулся" ??? В данном случае o2 ?
Нет же, суть AND в том, чтобы сигнализировать о фэйле через возвращаемое значение. В топку пользовательские типы, хотя бы для целых и указателей...

Цитата(502 @  3.2.2012,  19:34 Найти цитируемый пост)
это все есть в javascript
Ну это же прекрасно!

Цитата(borisbn @  3.2.2012,  19:38 Найти цитируемый пост)
переменные в javascript не типизированны, а в Си++ ты не можешь в зависимости от условия присвоить переменной либо false либо std::string, например. 
Вот-вот. Статическую типизацию можно частично забороть шаблонами (ну то есть как бы забороть, она останется в силе) или накрутить ручную динамическую... Я конечно больше за второй вариант, но он сливает в производительности, поэтому в С++ от статической лучше не отказываться.

Цитата(math64 @  3.2.2012,  19:40 Найти цитируемый пост)
Примерно так:
Сейчас не в состоянии распарсить, утром попробую )

Цитата(boostcoder @  3.2.2012,  20:13 Найти цитируемый пост)
а если ни одно не истинно, что возвращать?
Конструктор по умолчанию.

Цитата(boostcoder @  3.2.2012,  22:01 Найти цитируемый пост)
вот что получилось:
Спасибо, сейчас попытаюсь сконцентрироваться. Вариант с def тоже уместен.




--------------------
You're face to face
With man who sold the world
PM   Вверх
mes
Дата 4.2.2012, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



newbee, 
вот еще направление, если я прально понял задачу :
http://liveworkspace.org/code/962529beac6c...37a1ada28038e6e



--------------------
PM MAIL WWW   Вверх
newbee
Дата 4.2.2012, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Ууууух это вообще взрыв мозга))) Как это работает вообще не понятно)

Код

std::cout << Ext_OR((0)(Ext_AND((1)(0), 0))(2), def()) << std::endl; //wait: 2; recieve: 1 : FAIL
std::cout << Ext_OR((0)(Ext_AND((0)(1), 0))(2), def()) << std::endl; //wait: 2; recieve: 2 : OK


AND как-то неправильно раскрывается...

Добавлено через 9 минут и 53 секунды
mes, спасибо большое, эта идея у меня была, но не придумала как побороть явное создание вспомогательных объектов... Все же подобная запись AND-OR интересна в первую очередь потому, что часто позволяет сильно сократить размер кода.

Я обычно пользуюсь ленивостью || и && для записи условных выражений, но часто требуется получить значение выражения one || two || three, приходится писать лишний код... 


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 4.2.2012, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Код

int main() {
   std::cout << ( (0) ? (0) : (( !( 1 ) ? ( 0 ) : !( 0 ) ? ( 1 ) : ( 0 ) )) ? (( !( 1 ) ? ( 0 ) : !( 0 ) ? ( 1 ) : ( 0 ) )) : (2) ? (2) : (def()) ) << std::endl;
   std::cout << ( (0) ? (0) : (( !( 0 ) ? ( 0 ) : !( 1 ) ? ( 0 ) : ( 1 ) )) ? (( !( 0 ) ? ( 0 ) : !( 1 ) ? ( 0 ) : ( 1 ) )) : (2) ? (2) : (def()) ) << std::endl;
}


что тут не так? smile

Добавлено через 2 минуты и 8 секунд
по отдельности Ext_OR и Ext_AND работают как надо?
PM WWW   Вверх
newbee
Дата 4.2.2012, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(boostcoder @  4.2.2012,  01:30 Найти цитируемый пост)
что тут не так?
Я думаю, где-то скобок не хватает  smile 

Смотри, у тебя AND работает по-разному для AND(1,0) и AND(0,1), хотя в обоих случаях должен быть false (или значение по умолчанию, как сейчас сделано у тебя).

Добавлено через 3 минуты и 59 секунд
http://liveworkspace.org/code/972cca9cb2ab...74fa566a52388b9


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 4.2.2012, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  4.2.2012,  00:36 Найти цитируемый пост)
где-то скобок не хватает

нее ,компилятор бы ругался.

Цитата(newbee @  4.2.2012,  00:36 Найти цитируемый пост)
у тебя AND работает по-разному для AND(1,0) и AND(0,1), хотя в обоих случаях должен быть false (или значение по умолчанию, как сейчас сделано у тебя).

что-то накосячил... ща
PM WWW   Вверх
newbee
Дата 4.2.2012, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



ЗЫ. Прикольный ты себе домен выбрал, уже скольок раз вижу, а кажется lispworks.com ))

ЗЫЫ Модераторы, пожалуйста исправьте заголовок: "помогитЕ", я когда вижу эту ошибку, хочу убить автора.


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 4.2.2012, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  4.2.2012,  00:43 Найти цитируемый пост)
ЗЫЫ Модераторы, пожалуйста исправьте заголовок

это ты сама можешь сделать. "редактировать" на топике.

Добавлено через 2 минуты и 35 секунд
Цитата(newbee @  3.2.2012,  16:02 Найти цитируемый пост)
Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления.

ты тут не ошиблась?

а то я сделал так, что возвращает результат последнего истинного выражения)
PM WWW   Вверх
newbee
Дата 4.2.2012, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Заголовок не дает исправить, только текст...

Добавлено @ 00:50
Цитата(boostcoder @  4.2.2012,  01:44 Найти цитируемый пост)
ты тут не ошиблась?

Цитата(boostcoder @  4.2.2012,  01:44 Найти цитируемый пост)
Правильный AND (или цепочка из них) должен последовательно выполнять выражения и в случае истинности их всех возвращать результат последнего вычисления.


Понимаешь, это тот же оператор AND по сути, только в случае успешной проверки (AND 1 2 3), возвращаем 3 вместо true, в случае неудачной (AND 1 0 2), возвращаем 0.

Это сообщение отредактировал(а) newbee - 4.2.2012, 00:51


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 4.2.2012, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вот:
Код

#include <iostream>
#include <boost/preprocessor.hpp>

#define Ext_OR_SUBCOND(unused, idx, seq) \
   (BOOST_PP_SEQ_ELEM(idx, seq)) \
   ? \
   (BOOST_PP_SEQ_ELEM(idx, seq)) \
   :

#define Ext_OR(seq, def) \
   ( \
      BOOST_PP_REPEAT( \
         BOOST_PP_SEQ_SIZE(seq), \
         Ext_OR_SUBCOND, \
         seq \
      ) \
      (def) \
   )


#define Ext_AND_SUBCOND(unused, idx, tuple) \
   ( \
      BOOST_PP_SEQ_ELEM( \
         idx, \
         BOOST_PP_TUPLE_ELEM(2, 0, tuple) \
      ) \
   ) \
   BOOST_PP_IF( \
      BOOST_PP_NOT_EQUAL( \
         BOOST_PP_ADD(idx, 1), \
         BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(2, 0, tuple)) \
      ), \
      && , \
      \
   )
   

#define Ext_AND(seq, def) \
   ( \
      ( \
         BOOST_PP_REPEAT( \
            BOOST_PP_SEQ_SIZE(seq), \
            Ext_AND_SUBCOND, \
            (seq,def) \
         ) \
      ) \
      ? \
      ( \
         BOOST_PP_SEQ_ELEM( \
            BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
            seq \
         ) \
      ) \
      : (def) \
   )

int def() {
   return -1;
}

int main() {
   std::cout << Ext_OR((0)(Ext_AND((1)(0), 0))(2), def()) << std::endl; //wait: 2; recieve: 1 : FAIL
   std::cout << Ext_OR((0)(Ext_AND((0)(1), 0))(2), def()) << std::endl; //wait: 2; recieve: 2 : OK
}

http://liveworkspace.org/code/f35d3794bc73...ff02fba37c68e15

препроцессированный код:
Код

int main() {
   std::cout << ( (0) ? (0) : (( ( ( 1 ) && ( 0 ) ) ? ( 0 ) : (0) )) ? (( ( ( 1 ) && ( 0 ) ) ? ( 0 ) : (0) )) : (2) ? (2) : (def()) ) << std::endl;
   std::cout << ( (0) ? (0) : (( ( ( 0 ) && ( 1 ) ) ? ( 1 ) : (0) )) ? (( ( ( 0 ) && ( 1 ) ) ? ( 1 ) : (0) )) : (2) ? (2) : (def()) ) << std::endl;
}


все правильно?

Это сообщение отредактировал(а) boostcoder - 4.2.2012, 01:26
PM WWW   Вверх
mes
Дата 4.2.2012, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



boostcoder, если я правильно понял, то 
OR возвращает первое истинное, либо последнее если такого нет..
AND возвращает первое ложное, либо последнее если такого нет..
def  не нужен


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  4.2.2012,  01:22 Найти цитируемый пост)
def  не нужен 

ну вроде как да...

Добавлено @ 01:35
все равно не понимаю..
если не будет def, то что вернуть в случае лжи в следующем примере?
Код

( b1 ) && ( b2 ) && ( b3 ) ? ( b3 ) : def()


Это сообщение отредактировал(а) boostcoder - 4.2.2012, 01:38
PM WWW   Вверх
mes
Дата 4.2.2012, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



newbee,  логика работы операторв верна ? :
http://liveworkspace.org/code/6ca831342831...f7cb826178a2406

Добавлено через 2 минуты и 19 секунд
Цитата(boostcoder @  4.2.2012,  00:29 Найти цитируемый пост)
если не будет def, то что вернуть в случае лжи в следующем примере?

первый ложный smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  4.2.2012,  01:43 Найти цитируемый пост)
newbee,  логика работы операторв верна ? :
http://liveworkspace.org/code/6ca831342831...f7cb826178a2406

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

Цитата(mes @  4.2.2012,  01:43 Найти цитируемый пост)
первый ложный

тогда записывать тернарное выражение нужно так?:
Код

!(b1)?(b1)
   :!(b2)?(b2)
      :!(b3)?(b3);

PM WWW   Вверх
mes
Дата 4.2.2012, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  4.2.2012,  00:53 Найти цитируемый пост)
судя по примеру в топике, предполагается в качестве выражений использовать и функции/методы.

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



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  4.2.2012,  02:00 Найти цитируемый пост)
для начала то хотелось бы с логикой разобраться

ааа, понял smile
PM WWW   Вверх
mes
Дата 4.2.2012, 02:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  4.2.2012,  00:53 Найти цитируемый пост)
тогда записывать тернарное выражение нужно так?:

полагаю что так :
Код

!(b1)?(b1)
   :!(b2)?(b2)
      :(b3);




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 02:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  4.2.2012,  02:02 Найти цитируемый пост)
:(b3);

но b3 вообще не проверяется.

Добавлено через 1 минуту и 8 секунд
Цитата(newbee @  4.2.2012,  00:48 Найти цитируемый пост)
в случае успешной проверки (AND 1 2 3), возвращаем 3

хотя из примера так и выходит...
PM WWW   Вверх
mes
Дата 4.2.2012, 02:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  4.2.2012,  01:06 Найти цитируемый пост)
но b3 вообще не проверяется. 


а зачем ? если оно ложно значит вернется ложь, если верное, то вернется правда)



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 02:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



а для OR в случае лжи во всех выражения, что возвращать?
моцг уже спать просится..

Добавлено через 28 секунд
Цитата(mes @  4.2.2012,  02:08 Найти цитируемый пост)
если оно ложно значит вернется ложь, если верное, то вернется правда

да-да.

Добавлено через 8 минут и 33 секунды
в общем, этот код правильный? smile 
Код

int main() {
   int b1=1, b2=2, b3=3;

   std::cout << ( (b1) ? (b1) : (b2) ? (b2) : ( b3 ) << std::endl;
   std::cout << ( !(b1) ? (b1) : !(b2) ? (b2) : ( b3 ) << std::endl;
}


PM WWW   Вверх
mes
Дата 4.2.2012, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  4.2.2012,  01:10 Найти цитируемый пост)
а для OR в случае лжи во всех выражения, что возвращать?


Цитата(mes @  4.2.2012,  00:22 Найти цитируемый пост)
OR возвращает первое истинное, либо последнее если такого нет..
AND возвращает первое ложное, либо последнее если такого нет..


т.е. таже самая, тернарная конструкция, но без !

Добавлено через 1 минуту и 13 секунд
Цитата(boostcoder @  4.2.2012,  01:10 Найти цитируемый пост)
в общем, этот код правильный?

в моем понимании вопроса да smile



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2012, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  4.2.2012,  02:19 Найти цитируемый пост)
в моем понимании вопроса да

в моем тоже smile
Код

#include <iostream>
#include <boost/preprocessor.hpp>

#define Ext_OR_SUBCOND(unused, idx, seq) \
   (BOOST_PP_SEQ_ELEM(idx, seq)) \
   ? \
   (BOOST_PP_SEQ_ELEM(idx, seq)) :

#define Ext_OR(seq) \
   ( \
      BOOST_PP_REPEAT( \
         BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
         Ext_OR_SUBCOND, \
         seq \
      ) ( \
         BOOST_PP_SEQ_ELEM( \
            BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
            seq \
         ) \
      ) \
   )

#define Ext_AND_SUBCOND(unused, idx, seq) \
   !(BOOST_PP_SEQ_ELEM(idx, seq)) \
   ? \
   (BOOST_PP_SEQ_ELEM(idx, seq)) :

#define Ext_AND(seq) \
   ( \
      BOOST_PP_REPEAT( \
         BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
         Ext_AND_SUBCOND, \
         seq\
      ) ( \
         BOOST_PP_SEQ_ELEM( \
            BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(seq), 1), \
            seq \
         ) \
      ) \
   )

int main() {
   int b1=1, b2=2, b3=3;

   std::cout << Ext_OR ((b1)(b2)(b3)) << std::endl; // 1
   std::cout << Ext_AND((b1)(b2)(b3)) << std::endl; // 3
   std::cout << Ext_OR((0)(Ext_AND((1)(0)))(2)) << std::endl; //wait: 2; recieve: 1 : FAIL
   std::cout << Ext_OR((0)(Ext_AND((0)(1)))(2)) << std::endl; //wait: 2; recieve: 2 : OK
}

http://liveworkspace.org/code/3fee4b8abd6a...1412183b759e6ec
вывод:
Цитата

1
3
2
2

ожидания ТС подтверждаются.


Это сообщение отредактировал(а) boostcoder - 4.2.2012, 02:29
PM WWW   Вверх
volatile
Дата 4.2.2012, 02:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Вопрос к даме. Это кальку с какого языка вы пытаетесь реализовать на С++?
что-то имхо очень скриптовое... (и конечно не типизированное)

PM MAIL   Вверх
borisbn
Дата 4.2.2012, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(volatile @  4.2.2012,  02:57 Найти цитируемый пост)
Это кальку с какого языка вы пытаетесь реализовать на С++?

Цитата(boostcoder @  3.2.2012,  16:12 Найти цитируемый пост)
ты таки на лиспе пишешь?

Цитата(newbee @  4.2.2012,  00:43 Найти цитируемый пост)
а кажется lispworks

 smile 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 5.2.2012, 00:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



как-то не очень удобно в использовании получается
Цитата(boostcoder @  4.2.2012,  02:26 Найти цитируемый пост)
   std::cout << Ext_OR((0)(Ext_AND((1)(0)))(2)) << std::endl;

Вот мой вариант:
Код

template <typename T>
class Saver {
public:
  friend bool operator || (T t, Saver& saver) { saver.save = t; return !!t; }
  friend bool operator && (T t, Saver& saver) { saver.save = t; return !t; }
  T get() { return save; }
private:
  T save;
};

// a && b --> нужно a ? (b ? a : 0) : 0 или !a ? 0 : b ? a : 0 получается !a ? a : b
#define AND && saver ? saver.get() :
// a || b --> a ? a : b
#define OR || saver ? saver.get() :

int f() { return 0; }
int main()
{
Saver<int> saver;
int a = 1, b = 2, c = 0;
cout << (a OR b) << endl;
cout << (a OR c) << endl;
cout << (c OR b) << endl;
cout << (c OR a OR b) << endl;
cout << (c OR (a AND b)) << endl;
cout << (f() OR (a AND b)) << endl;
}

OR работает так, как надо.
AND при истинности возвращает последний элемент, а не первый.

PM   Вверх
mes
Дата 5.2.2012, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(math64 @  4.2.2012,  23:29 Найти цитируемый пост)
AND при истинности возвращает последний элемент, а не первый.

при истинности последний и должен )



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 5.2.2012, 02:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



math64, еще бы от Saver`а избавиться...
PM WWW   Вверх
newbee
Дата 5.2.2012, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Мммм и еще раз здравствуйте smile

Друзья, из вашего сумбурного диалога я так и не поняла, поняли ли вы меня... Еще раз: функции OR и AND - не какие-то сферические штуковины со знакомыми названиями! Это аналогия обычных операторов && и ||, которые могут принимать  >=0 параметров (на практике сойдет >=2). Как работает обычный ||: он последовательно вычисляет аргументы и как как только наткнется на истинный результат, возвращает true, OR же вместо true возвращает само это вычисленное значение. Если все аргументы ложны, и ||, и OR возвращают 0.

Обычный &&: последовательно вычисляются аргументы, при встрече первого ложного результата возвращается 0, в AND - аналогично. Если результат вычисления всех аргументов истинен, && возвращает true, AND возвращает последний результат.

mes, у тебя функции неленивые (поправь, если я не права), для AND/OR это недопустимо... В лучшем случае это обернется легко обнаруживаемым сегфолтом, в худшем - сложно уловимыми побочными эффектами. По логике правильно.

volatile, Common Lisp. Не скриптовое, динамически типизированное.

math64, спасибо за помощь, сейчас буду разбираться...

boostcoder, тебе вообще огромное спасибо, сейчас тоже потыкаю твой последний вариант... Я вот сижу смотрю на раскрытие макроса и понимаю, что его аргументы (b1)(b2)(b3) будут вычисляться далеко не один раз... Значит нужно вначале раскрытия генерировать примерно следующее:
Код

typeof(b1) __tmp_1=b1;
typeof(b2) __tmp_2=b2;
typeof(b3) __tmp_3=b3;


И потом внутри мега ?:-конструкции использовать __tmp_X вместо bX. Мне сложно судить наверняка, но при нынешнем однопроходном раскрытии макроса это нереально. И отчасти вдогонку к этому, не мог бы ты объяснить без привязки к BOOST_PP, каким образом препроцессор си раскрывает макрос macro((b1)(b2))? То есть получается, он не просто разбивает входные аргументы, а распарсивает выражение...


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 5.2.2012, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  5.2.2012,  22:23 Найти цитируемый пост)
(b1)(b2)(b3) будут вычисляться далеко не один раз... Значит нужно вначале раскрытия генерировать примерно следующее:

и выражения перестанут быть ленивыми.

ты это.. протесть то что у меня получилось, чтоб я убедился в том что правильно тебя понял и сделал. потом подумаем над доделками.

Цитата(newbee @  5.2.2012,  22:23 Найти цитируемый пост)
(b1)(b2)

в терминах boost.preprocessor - это последовательность. я же, итерируюсь по последовательности, и на каждой итерации раскрываю часть общего выражения.

Добавлено через 10 минут и 1 секунду
Цитата(newbee @  5.2.2012,  22:23 Найти цитируемый пост)
при нынешнем однопроходном раскрытии макроса это нереально.

можно дважды пройтись по последовательности.
PM WWW   Вверх
volatile
Дата 5.2.2012, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(newbee @  5.2.2012,  22:23 Найти цитируемый пост)
Common Lisp. Не скриптовое, динамически типизированное.

Ну да. динамически типизированное. там это имеет практический смысл.

В С++ даже если и получиться написать (кстати неплохие варианты тут предлагали, ребята постарались!)
но использовать это почти не получится.

Все аргументы должны быть приводимы к одному типу, и кроме того еще и к bool (если я правильно понял..)
Где это можно использовать?
Не, ну можно конечно что-то придумать такое, где такое применить, но это имхо, искусственное притягивание за уши.
На приктике (при статической типизации) это практически бемполезная конструкция, имхо конечно.


Это сообщение отредактировал(а) volatile - 5.2.2012, 23:58
PM MAIL   Вверх
newbee
Дата 6.2.2012, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



boostcoder, я поэксперементировала с твоими вариантами, с точки зрения логики раскрытия все правильно! Ты прав, сразу раскрывать все аргументы нельзя - привет, ленивость! Но нашлась мысля smile Макросы можно разворачивать в ({})-форму, это расширение GCC, тогда на каждой итерации можно сначала вычислить результат, а потом его проверять!
Код
std::cout<<(1?({int res=foo();res?res:-1;}):0)<<std::endl;//просто пример ({})


Цитата(boostcoder @  5.2.2012,  23:45 Найти цитируемый пост)
в терминах boost.preprocessor - это последовательность. я же, итерируюсь по последовательности, и на каждой итерации раскрываю часть общего выражения.
Это я поняла по кодуsmile Мне любопытно, каким образом буст обманывает препроцессор и итерирует не по аргументам, а по свой скобочной коллекции. Интуиция подсказывает, что внутри это оборачивается в вызов другого макроса, очередной скобочный аргумент передается ему в качестве аргумента... Но как это происходит не пойму smile Исходники буст-препроцессора я не осилила, поэтому и любопытствую, что за трюк такой... Если не сложно.

Цитата(volatile @  6.2.2012,  00:56 Найти цитируемый пост)
а приктике (при статической типизации) это практически бемполезная конструкция, имхо конечно.
А на моей практике это очень нужная конструкция. Мы с тобой просто программируем по-разному, которая экономит много строк кода. Где-то на первой странице я приводила немного надуманый, но наглядный пример.


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 6.2.2012, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  6.2.2012,  08:44 Найти цитируемый пост)
Макросы можно разворачивать в ({})-форму, это расширение GCC

не знал. попробую.

Цитата(newbee @  6.2.2012,  08:44 Найти цитируемый пост)
Интуиция подсказывает, что внутри это оборачивается в вызов другого макроса, очередной скобочный аргумент передается ему в качестве аргумента.

именно так.

к примеру простой макрос BOOST_PP_SEQ_SIZE(): https://github.com/ryppl/boost-svn/blob/mas...or/seq/size.hpp

макрос:
var = BOOST_PP_SEQ_SIZE((a)(b)©)

развернется в:
var = BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_3

который в свою очередь описан как:
# define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_3 3

т.е. весь boost.preprocessor работает по нескольким основным принципам. либо по кол-ву аргументов, либо специализациями для всех возможных количеств аргументов.
все на самом деле очень просто.

Добавлено через 3 минуты и 58 секунд
или я не понял вопроса...

Добавлено через 8 минут и 57 секунд
Цитата(newbee @  6.2.2012,  08:44 Найти цитируемый пост)
Макросы можно разворачивать в ({})-форму, это расширение GCC

хм..
http://liveworkspace.org/code/35bcbcc90f05...d71d9b551f41499

дай ссылку на описание расширения.
PM WWW   Вверх
newbee
Дата 6.2.2012, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(boostcoder @  6.2.2012,  10:34 Найти цитируемый пост)
дай ссылку на описание расширения. 
У тебя включен pedantic.

http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

Компилируй с -std=gnu++98 или -std=gnu++0x


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 6.2.2012, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  6.2.2012,  09:53 Найти цитируемый пост)
У тебя включен pedantic.

угу.

в общем работает.
попробую доделать..

Добавлено через 2 минуты и 31 секунду
mes, а Вы свой вариант будите доделывать? просто любопытно посмотреть на решение.
я тут еще подумал... для функционального программирования в с++, разработали boost.phoenix. еще попробую с его помощью решить задачу.
PM WWW   Вверх
mes
Дата 6.2.2012, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



boostcoder, мой вариант придет к буст лямбде smile

Цитата(boostcoder @  6.2.2012,  09:04 Найти цитируемый пост)
 разработали boost.phoenix.

еще не приходилось сталкиваться smile



Это сообщение отредактировал(а) mes - 6.2.2012, 10:13


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 6.2.2012, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  6.2.2012,  10:13 Найти цитируемый пост)
мой вариант придет к буст лямбде

 smile 
PM WWW   Вверх
boostcoder
Дата 9.2.2012, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



newbee, итак.
давай посмотрим на препроцессированный вариант твоих тестов:
Код

int main() {
   int b1=0, b2=1, b3=2;

   std::cout << Ext_OR((b1)(Ext_AND((b2)(b1)))(b3)) << std::endl; //wait: 2; recieve: 2
   std::cout << Ext_OR((b1)(Ext_AND((b1)(b2)))(b3)) << std::endl; //wait: 2; recieve: 2
}

результат:
Код

int main() {
   int b1=0, b2=1, b3=2;

   std::cout << ( (b1) ? (b1) : (( !(b2) ? (b2) : ( b1 ) )) ? (( !(b2) ? (b2) : ( b1 ) )) : ( b3 ) ) << std::endl;
   std::cout << ( (b1) ? (b1) : (( !(b1) ? (b1) : ( b2 ) )) ? (( !(b1) ? (b1) : ( b2 ) )) : ( b3 ) ) << std::endl;
}


теперь нужно выявить вложенность "скопов" для того чтоб определить в каком скопе какое выражение должно вычисляться...

Добавлено @ 01:32
лишние скобки уберем..

Добавлено @ 01:36
вот что получилось:
Код

int main() {
   int b1=0, b2=1, b3=2;

   std::cout << (
      (b1)
      ?(b1)
         :!(b2)
            ?(b2)
               :(b1)
            ?!(b2)
               ?(b2)
                  :(b1)
               :(b3)
   ) << std::endl;

   std::cout << (
      (b1)
      ?(b1)
         :!(b1)
            ?(b1)
               :(b2)
            ?!(b1)
               ?(b1)
                  :(b2)
               :(b3)
   ) << std::endl;
}



Это сообщение отредактировал(а) boostcoder - 9.2.2012, 01:37
PM WWW   Вверх
newbee
Дата 9.2.2012, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



boostcoder, у тебя сложно раскрывается AND. Я для наглядности буду возвращать нули вместо самих вычисленных значений.

Код

(and b1 b2 b3) -> b1?(b2?(b3?b3:0):0):0 // так имхо логичнее
(or b1 b2 b3) -> b1?b1:(b2?b2:(b3?b3:0)) //у тебя по-моему так и есть


Теперь... Смотри, внутри OR и AND излишне следовать правилу раскрытия элемента последовательности x?x: Если x - вложенный AND или OR, его можно прямо встроить в выражение. Я не знаю, можно ли это сделать на дефайнах... Это необязательно. Таким образом твой пример принял бы форму
Код

(or b1 (and b1 b2) b3) -> b1?b1:(b1?(b2?b2:0):(b3?b3:0))
/* или
   if?
     then
    :else
 */
b1?
  b1
 :(b1?
     (b2?
        b2
       :0)
    :(b3?
        b3
       :0))


Теперь давай подумаем со скопами...

Код

(and b1 b2 b3) ->  b1?(b2?(b3?b3:0):0):0 -> 

b1?
  (b2?
     (b3?
        b3
       :0)
    :0)
 :0 ->

({typeof(b1) _1=b1;
  _1?
    ({typeof(b2) _2=b2;
      _2?
        ({typeof(b3) _3=b3;
          _3?
            _3
           :0;})
       :0;})
   :0;})


И аналогично должно быть с OR. Потом напишу, если надо. Я нигде не накосячила?


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 9.2.2012, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вроде въехал..

Цитата(newbee @  9.2.2012,  11:03 Найти цитируемый пост)
Я нигде не накосячила?

по моему - нет.
PM WWW   Вверх
math64
Дата 10.2.2012, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Код

#define OR(var,def) ({typeof(var) _tmp = (var); _tmp?_tmp:(def);})
#define TEST(var) OR(var,0)
#define AND(var1,var2) ((var1)?(var2):0)
int main() {
int v1 = 1, v2 = 2, v3 = 3;
// v1 or v2 or v3
cout << OR(v1,OR(v2,TEST(v3))) << endl;
// v1 and v2 and v3
cout << AND(v1,AND(v2,TEST(v3))) << endl;
// v1 and (v2 or v3)
cout << AND(v1,OR(v2,TEST(v3))) << endl;
// v1 or (v2 and v3)
cout << OR(v1,AND(v2,TEST(v3))) << endl;
}

(не проверял)
PM   Вверх
boostcoder
Дата 10.2.2012, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



newbee, смотри какое дело.
код:
Код

int main() {
   int b1=0, b2=1, b3=2;
   std::cout << (
      ({typeof(b1) _1=b1;       // level +1
      _1?
         ({typeof(b2) _2=b2;    // level +2
            _2?
            ({typeof(b3) _3=b3; // level +3
               _3?
                  _3
               :0;
            })                  // level -3
            :0;
         })                     // level -2
         :0;
      })                        // level -1
   ) << std::endl;
}

как ты можешь видеть, тут вложенные скопы. но препроцессор не может рекурсию. он однопроходный.

идеи?
PM WWW   Вверх
boostcoder
Дата 10.2.2012, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



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

на примере Ext_OR((b1)(b2)(b3)):
Код

({typeof(b1) _0 = b1; (_0) ? (_0) : ({typeof(b2) _1 = b2; (_1) ? (_1) : b3

вроде то, что надо.

но при попытке использовать вложенные макросы "Ext_OR ((b1)(b2)(b3)(Ext_OR ((b1)(b2)(b3))))" получаю ошибку препроцессора.
и правильно. при первом проходе еще ничего не сгенеренно. по этому препроцессор генерит нормально, не смотря на непарные скобки. но при втором проходе, он, "видя" такое ( smile ) синтаксически не правильное "произведение" - спотыкается.

идеи будут?

Добавлено через 2 минуты и 6 секунд
math64, не правильно. в твоем коде все равно выражения будут вычисляться не единожды.
PM WWW   Вверх
newbee
Дата 10.2.2012, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Бустик, я совсем запуталась в твоих буст-пппроблемах :(

Сделала OR сама, ленивый, молодежный, современный! smile

Код

#include"PP_NARG.h"
#include"PP.h"
#include"PP_OR.h"

#define OR(...) PP_CONCATENATE(PP_OR_,PP_NARG(__VA_ARGS__))(__VA_ARGS__)

#include<iostream>

int foo(){
 std::cout<<__PRETTY_FUNCTION__<<std::endl;
 return 0;}

int bar(){
 std::cout<<__PRETTY_FUNCTION__<<std::endl;
 return 3;}

int main(){
 std::cout<<"out: "<<OR(foo(),OR(foo(),0),bar(),bar(),42)<<std::endl;
 std::cout<<"out: "<<OR(foo(),OR(bar(),foo()),bar(),bar(),42)<<std::endl;
 std::cout<<"out: "<<OR(42,OR(foo(),0),bar(),bar(),42)<<std::endl;
 return 0;}


Цитата
int foo()
int foo()
int bar()
out: 3
int foo()
int bar()
out: 3
out: 42


Критика, вопросы, предложения приветствуются!

PS. В архиве несколько вспомогательных файлов.

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  OR_AND.tar 20,00 Kb


--------------------
You're face to face
With man who sold the world
PM   Вверх
k0rvin
Дата 10.2.2012, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(tzirechnoy @ 3.2.2012,  17:25)
Шли бы Вы хаскель изучать, а? Тем более, что через монады это действительно делается, в том числе и в плюсах.

Жду решения на Хаскелле.


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
boostcoder
Дата 10.2.2012, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



слуш.
а что если макрос будет раскрываться так?
Код

Ext_OR((b1)(b2)(b3));

...

({
typeof(b1) _0 = (b1);
typeof(b2) _1 = (b2);
typeof(b3) _2 = (b3);

(... ternarka ...);
})

т.е. все выражения будут вычисляться сразу. а?
или не актуально?

Добавлено через 2 минуты и 33 секунды
Цитата(newbee @  10.2.2012,  12:57 Найти цитируемый пост)
OR_AND.tar 20,00 Kb

а в архиве какие конкретно вирусы? smile

Добавлено через 5 минут и 48 секунд
вообще у тебя не плохо получилось. и без зависимости от буста smile
PM WWW   Вверх
newbee
Дата 10.2.2012, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(boostcoder @  10.2.2012,  14:35 Найти цитируемый пост)

т.е. все выражения будут вычисляться сразу. а?
или не актуально?
Да нет, актуально. Интересно, как это будет выглядеть на бусте. Я когда тему создавала сразу предполагала, что ты родишь что-нибудь буст-препроцессорное...

Но сначала вычислять никак нельзя. Посмотри любой свой код, с нелинивыми операторами if, || и && он скорее всего рассыпется.

Добавлено через 2 минуты и 48 секунд
Цитата(boostcoder @  10.2.2012,  14:35 Найти цитируемый пост)
а в архиве какие конкретно вирусы?
Он несжатый)

Цитата(boostcoder @  10.2.2012,  14:35 Найти цитируемый пост)
вообще у тебя не плохо получилось.
Потому что нагенерировала специфичных под задачу макросов? Хотела сделать более обобщенный FOREACH, но там были бы сложности и неудобства. Или что еще плохо?



--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 10.2.2012, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  10.2.2012,  13:43 Найти цитируемый пост)
Но сначала вычислять никак нельзя. Посмотри любой свой код, с нелинивыми операторами if, || и && он скорее всего рассыпется.

ну да..

Добавлено через 11 секунд
ладно, думаю...
PM WWW   Вверх
newbee
Дата 10.2.2012, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Блин, косая я. Не плохо получилось)) Неплохо, да! ))


--------------------
You're face to face
With man who sold the world
PM   Вверх
boostcoder
Дата 10.2.2012, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(newbee @  10.2.2012,  13:43 Найти цитируемый пост)
Потому что нагенерировала специфичных под задачу макросов?

это не стёб был.
в самом деле нормально получилось. просто и понятно.

Добавлено через 26 секунд
Цитата(newbee @  10.2.2012,  13:46 Найти цитируемый пост)
косая я

 smile

Добавлено через 14 минут и 49 секунд
Цитата(newbee @  10.2.2012,  13:46 Найти цитируемый пост)
Неплохо

ну..мне простительно. русский мне не родной язык smile 
PM WWW   Вверх
math64
Дата 10.2.2012, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Вычислятся быдут один раз. Проверяться и копироваться - да, много раз (при сложной формуле).
Идеи? Не пытаться делать макрос в переменным числом агрументов, генерирующих всё выражение, а набор макросов генерирующих фрагменты выражения.
Временной для запоминания переменной можно обойтись одной, поэтому можно опробовать что-то типа
Код

#define BEGIN(type) ({type _tmp;
#define BEGIN2(var) ({typeof(var) _tmp = var;
#define END ;})
#define AND == 0 ? 0 :
#define SAVE(var) (tmp = var)
#define OR   != 0  ? _tmp :

Возможно использовать набор макросов AND2(var1,var2), AND3(var1,var2,var3) и т.д.

Добавлено через 5 минут и 50 секунд
Цитата(boostcoder @  10.2.2012,  13:35 Найти цитируемый пост)
т.е. все выражения будут вычисляться сразу. а?

Неправильно. Выражения должны вычисляться только после проверки предыдущих:
Код

list<int> a;
count << AND(a.size(), a[0]) << endl; // нельзя вычислять a[0] до проверки размера списка


PM   Вверх
newbee
Дата 10.2.2012, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



math64, я не понимаю, что у тебя за бегины и енды... Ты что-то недокопипастил?..

Добавлено через 10 минут и 41 секунду
Кстати... Есть ли у кого-нибудь идеи, как избавиться от typeof и ({}) расширений? На шаблонах или хз как еще... Возможно придется компилировать под винду, там я предпочитаю компилятор MSVC.


--------------------
You're face to face
With man who sold the world
PM   Вверх
vol4ek
Дата 10.2.2012, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


конь в пальто
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 1.5.2011
Где: Минск

Репутация: 0
Всего: 0



Цитата(newbee @  10.2.2012,  19:13 Найти цитируемый пост)
math64, я не понимаю, что у тебя за бегины и енды... Ты что-то недокопипастил?..


на VB похоже...  smile 

PM MAIL ICQ   Вверх
math64
Дата 10.2.2012, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(newbee @  10.2.2012,  19:13 Найти цитируемый пост)
math64, я не понимаю, что у тебя за бегины и енды... Ты что-то недокопипастил?

Отвечал на последнее сообщение предыдущей страницы - не заметил что есть ещё сообщения.
Это просто идеи, как построить макросы - не проработано до конца.
Если типы всех переменных одинаковы, можно использовать только одну временную переменную, которая объявлена в макросе BEGIN(type)
Макрос END закрывает объявление
Макросы, используемые в середине не проработаны.
Идея c AND2(), AND3(), OR2(), OR3() - уже не актуальна, Вы сделали лучше.
Как избавиться от ({}) - я уже предлагал - класс Saver, его можно переделать, чтобы был синглетоном и замоминал всё что можно как Variant, но typeof() всё равно нужен, чтобы получить запомненное значение нужного типа. Но если комплятор поддерживает ({}) - лучше использовать их (в объявлении макросов - условная трансляция)

PM   Вверх
boostcoder
Дата 10.2.2012, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(math64 @  10.2.2012,  18:37 Найти цитируемый пост)
Неправильно.

не нужно повторять.

Цитата(math64 @  10.2.2012,  18:37 Найти цитируемый пост)
Не пытаться делать макрос в переменным числом агрументов, генерирующих всё выражение, а набор макросов генерирующих фрагменты выражения.

жуть какая-то) как же такое юзать? оО

Цитата(math64 @  10.2.2012,  19:52 Найти цитируемый пост)
Если типы всех переменных одинаковы

а если нет?

PM WWW   Вверх
math64
Дата 10.2.2012, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(boostcoder @  10.2.2012,  20:05 Найти цитируемый пост)
не нужно повторять.

уже объяснял - не прочитал всё до конца
Цитата(boostcoder @  10.2.2012,  20:05 Найти цитируемый пост)
а если нет?

если нет -   x ? y : z всё равно не скомпилируется, или все должны приводиться к типу первого выражения, его и использовать, или объявить тип переменной самостоятельно.
Код

  int* a = 0;
  long* b = 0;
  void* p = a ? a : b; // error: conditional expression distinct pointer types ...

В этом случае тип результата нужно объявлять самостоятельно
Код

void* p = ({void* tmp; (tmp = a) ? tmp : (tmp = b) ? b : 0; });


Правда, есть случай, когда даже при одном типе объединять нельзя:
Код

int& foo();
int& bar();
int zero = 0;
int& rzero = zero;
int& r = ({ int&tmp = foo();
              tmp ? tmp :
              ({ int&tmp=bar();
                 tmp?tmp:rzero;
              });
            });

Но он тоже не компилируется - результат ({ }) не int&, а int

PM   Вверх
boostcoder
Дата 10.2.2012, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(math64 @  10.2.2012,  21:14 Найти цитируемый пост)
если нет -   x ? y : z всё равно не скомпилируется

да. туплю.

PM WWW   Вверх
math64
Дата 11.2.2012, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Нужно доработать макросы AND и OR, чтобы принимали переменное число агрументов (как в PP_NARG.h или из boost) и моглм комбинироваться.
TEST используется для задания значения по умолчанию для обычных типов 
TESTR используется для задания значения по умолчанию для ссылок
для ссылок желательно обезопасить от порчи значение по умочанию.
Код

#define TEST(def,and_or) ({ typeof(def) _tmp = def; and_or; _tmp; })
#define AND(var1,var2) if(var1) if(typeof(var2) _and2=(var2)) _tmp = _and2;
#define OR(var1,var2) if(typeof(var1) _or = (var1)) _tmp = _or; else if(typeof(var2) _or=(var2)) _tmp = _or;
#define TYPEOFR(var) typeof(&(var))
#define TESTR(def,and_or) *({ typeof(&(def)) _tmp = &(def); and_or; _tmp; })
#define ANDR(var1,var2) if(var1) { typeof(&(var2)) _and = &(var2); if(*_and) _tmp = _and; }
#define ORR(var1,var2) { typeof(&(var1)) _or = &var1; if(*_or) _tmp = _or; else { typeof(&(var2)) _or=&(var2); if(*_or) _tmp = _or; }}

#include <iostream>
using namespace std;

int& foo() {
cout << "foo()" << endl;
static int res = 0;
return res;
}

int& bar() {
cout << "bar()" << endl;
static int res = 1;
return res;
}

int main() {

cout << TEST(0,OR(foo(),bar())) << endl;
cout << TEST(0,AND(foo(),bar())) << endl;
int zero = 0;
int& rzero = zero;
cout << "rzero:" << &rzero << endl;
cout << "foo():" << &foo() << endl;
cout << "bar():" << &bar() << endl;
TESTR(rzero,ORR(foo(),bar())) = 2;
int& r1 = TESTR(rzero,ORR(foo(),bar()));
cout << "r1:" << &r1 <<'='<< r1 << endl;
int& r2 = TESTR(rzero,ANDR(foo(),bar()));
cout << "r2:" << &r2 <<'='<< r2 << endl;
}


PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1561 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.