Модераторы: 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   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0592 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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