Re: наверно я многого хочу: поддержка конструкций
От: rg45 СССР  
Дата: 22.06.08 18:38
Оценка: :))
Здравствуйте, varnie, Вы писали:

V>
V> if ((const Foo *pFoo = getFoo()) == VALUE) {
V>    //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет
V>


Просьба в серьез не принимать:
for (const Foo* pFoo = getFoo(); pFoo == VALUE; ++pFoo) 
{
  //работаем далее с pFoo
}
//здесь уже pFoo нет

... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Справедливость выше закона. А человечность выше справедливости.
Re: наверно я многого хочу: поддержка конструкций
От: Кодт Россия  
Дата: 24.06.08 08:58
Оценка: :))
Здравствуйте, varnie, Вы писали:

Извращённый способ:
struct MatchFoo
{
    Foo value;
    Foo pattern;
    MatchFoo(Foo v, Foo p) : value(v), pattern(p) {}
    operator bool() const { return value == pattern; }
};

if(MatchFoo /*const*/ mf = MatchFoo(getFoo(), VALUE))
    std::cout << mf.value << "==" << VALUE << std::endl;


Обобщая:
template<class Value>
struct match_t
{
    Value value;
    bool matched;
    match_t(Value v, bool m) : value(v), matched(m) {}
    virtual operator bool() const { return matched; }
};

template<class Value, class Pred>
match_t<Value> match_if(Value v, Pred p) { return match_t<Value>(v, p(v)); }

template<class Value>
match_t<Value> match_with(Value v, Value p) { return match_t<Value>(v, v==p); }

int getFoo();
int const VALUE;
void test()
{
    if(match_t<int> mf = match_with(getFoo(), VALUE))
        std::cout << mf.value << "==" << VALUE << std::endl;
}


Поначалу хотел сделать на полиморфизме — хранить ссылку на тип, у которого перекрыт operator bool(),
template<class Value>
struct match_t
{
    Value value;
    match_t(Value v) : value(v) {}
    virtual operator bool() const = 0;
};
// и наследники, порождаемые функциями
template<class Value, class Pred>
struct match_if_t : match_t<Value>
{
    Pred pred;
    match_t(Value v, Pred p) : match_t(v), pred(p) {}
    virtual operator bool() const { return pred(value); }
};

template<class Value, class Pred> match_if_t<Value,Pred> match_if(Value v, Pred p)
    { return match_if_t<Value,Pred>(v,p); }
template<class Value> match_if_t<Value,binder2nd<equal_to<Value> > match_with(Value v, Value p)
    { return match_if_t<Value,binder2nd<equal_to<Value> >(v, bind2nd(equal_to<Value>(),p)); }

.....
    if(match_t<int> const& mf = match_with(getFoo(), VALUE))
        .....
.....

но сообразил, что здесь это из пушки по воробьям. Поскольку проверка предиката выполняется ровно один раз, то проще хранить не сам предикат, а его результат.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: наверно я многого хочу: поддержка конструкций
От: Sergey Россия  
Дата: 25.06.08 13:04
Оценка: +2
Roman Odaisky пишет:
> Чего на самом деле не хватает, так это using, как в C#:
>
> using(X x = getX())
> if(i_like(x) && x.is_very_nice())
> {
> . . .
> }
>
>
> В C++ это можно сделать только через for:
> http://www.rsdn.ru/forum/message/2397489.1.aspx
Автор: Roman Odaisky
Дата: 07.03.07


А чем это лучше обычных фигурных скобок?
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: наверно я многого хочу: поддержка конструкций
От: Sergey Россия  
Дата: 25.06.08 14:37
Оценка: +2
Roman Odaisky пишет:

>> > Чего на самом деле не хватает, так это using, как в C#:

>> > using(X x = getX())
>> > if(i_like(x) && x.is_very_nice())
>> > {
>> > . . .
>> > }
>> > В C++ это можно сделать только через for:
>> > http://www.rsdn.ru/forum/message/2397489.1.aspx
Автор: Roman Odaisky
Дата: 07.03.07

> <http://rsdn.ru/forum/message/2397489.1.aspx&gt;
Автор: Roman Odaisky
Дата: 07.03.07

>
> S>А чем это лучше обычных фигурных скобок?
>
> Тем, что можно использовать в макросах. Например:
>
> #define DOUBLE_FOR(decl1, decl2, cond1, cond2, upd1, upd2) \
> using(decl1) \
> for(decl2; (cond1) && (cond2); (upd1), (upd2))
>
>
> Иногда в макросах нужно вставить несколько объявлений, а for не подходит
> из-за break/continue, и фигурные скобки не подходят из-за того, что
> закрывающую скобку ставить некому.

Нда, странные у людей потребности...

> И вообще, код вроде

>
> doSomething();
>
> using(Lock lock(mutex))
> {
> doSomethingElse();
> }
>
>
> выглядит, по-моему, естественнее, чем фигурные скобки из ниоткуда:
>
> doSomething();
>
> {
> Lock lock(mutex);
>
> doSomethingElse();
> }

По-моему наоборот.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
наверно я многого хочу: поддержка конструкций
От: varnie  
Дата: 22.06.08 16:19
Оценка: :)
здравствуйте все.

интересуюсь, почему язык поддерживает конструкции вида:
 if (const Foo *pFoo = getFoo()) {
   //работаем далее с pFoo
 }
 //здесь уже pFoo нет

но не поддерживает
 if ((const Foo *pFoo = getFoo()) == VALUE) {
    //работаем далее с pFoo
 }
 //здесь уже pFoo нет

на подобное натыкаюсь зачастую, и приходится вместо этого писать:
 const Foo *pFoo = getFoo();
 if (pFoo){
    //работает далее с pFoo
 }
 //здесь уже pFoo нет

но немного не нравится, т.к. по логике сама переменная pFoo нам нужна только в теле блока if, а получается, что в моем последнем примере она будет доступна далее _после_ тела if. или я много хочу?
спасибо за комменты.
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re: наверно я многого хочу: поддержка конструкций
От: Аноним  
Дата: 22.06.08 17:51
Оценка: +1
И хорошо что это не работает. Поубивал бы..
Re: наверно я многого хочу: поддержка конструкций
От: _nn_ www.nemerleweb.com
Дата: 22.06.08 18:18
Оценка: -1
Здравствуйте, varnie, Вы писали:

На мой взгляд нужно просто избавляться от такого кода.
Лучше уже писать:
Foo& f = getFoo();
// работаем с f

А если getFoo проваливается выскакивает исключение
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: наверно я многого хочу: поддержка конструкций
От: Alexander G Украина  
Дата: 22.06.08 21:36
Оценка: +1
Здравствуйте, varnie, Вы писали:

V>
V> const Foo *pFoo = getFoo();
V> if (pFoo){
V>    //работает далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

V>но немного не нравится, т.к. по логике сама переменная pFoo нам нужна только в теле блока if, а получается, что в моем последнем примере она будет доступна далее _после_ тела if. или я много хочу?
V>спасибо за комменты.

Можно для этого использовать другой блок.


{ // Открыли блок в котором будет жить pFoo 
  const Foo *pFoo = getFoo();
  if (pFoo == VALUE)
  {
  }
  // здесь pFoo есть
} // а здесь уже рыбы нет.



Насколько я помню, такой синтаксис (объявление переменной прямо в if) в основном предназначается для даункастинга:
if (const *pBar = dynamic_cast<const Bar*>(getFoo()))
{
}
else if (const *pFoo = dynamic_cast<const Foo*>(getFoo()))
{
}
else if (...


Возможно, попытки применить этот синтаксис как-то по другому сродни попытке использовать for не для инициализации-проверки-инкремента итератора.
Русский военный корабль идёт ко дну!
Re[2]: наверно я многого хочу: поддержка конструкций
От: Kluev  
Дата: 24.06.08 09:06
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Просьба в серьез не принимать:

R>
R>for (const Foo* pFoo = getFoo(); pFoo == VALUE; ++pFoo) 
R>{
R>  //работаем далее с pFoo
R>}
R>//здесь уже pFoo нет
R>


Кстати это мысль. только ++pFoo лишнее, а так вполне годный немного обфуцированный код.
    for (Foo *p = foo(); p && p->zz == value;)
    {
        p->hurr_hurr();
    }
Re[2]: Так, IMHO, корректнее...
От: Erop Россия  
Дата: 24.06.08 20:59
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Просьба в серьез не принимать:

Анологично
R>
R>for (const Foo* pFoo = getFoo(); pFoo == VALUE; ) 
R>{
R>  //работаем далее с pFoo
    break;
R>}
R>//здесь уже pFoo нет
R>

R>
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Так, IMHO, корректнее...
От: rg45 СССР  
Дата: 25.06.08 11:35
Оценка: :)
Здравствуйте, Erop, Вы писали:

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


R>>Просьба в серьез не принимать:

E>Анологично
R>>
R>>for (const Foo* pFoo = getFoo(); pFoo == VALUE; ) 
R>>{
R>>  //работаем далее с pFoo
E>    break;
R>>}
R>>//здесь уже pFoo нет
R>>

R>>

Гм... Если вынести в отдельный топик, то флейм можно раздуть не слабее чем Минусы STL
Автор: gid_vvp
Дата: 23.08.06
или Зачем массиву итератор?
Автор: McSeem2
Дата: 09.05.08

--
Справедливость выше закона. А человечность выше справедливости.
Re: наверно я многого хочу: поддержка конструкций
От: Roman Odaisky Украина  
Дата: 25.06.08 12:54
Оценка: :)
Здравствуйте, varnie, Вы писали:

V>интересуюсь, почему язык поддерживает конструкции вида:

V>но не поддерживает
V>
V> if ((const Foo *pFoo = getFoo()) == VALUE) {
V>    //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

Потому, что это только частный случай. Потом ты еще захочешь if((X x = getX()).isGood()), if(isGood(X x = getX()))...

Чего на самом деле не хватает, так это using, как в C#:
using(X x = getX())
if(i_like(x) && x.is_very_nice())
{
    . . .
}

В C++ это можно сделать только через for: http://www.rsdn.ru/forum/message/2397489.1.aspx
Автор: Roman Odaisky
Дата: 07.03.07
До последнего не верил в пирамиду Лебедева.
Re[2]: наверно я многого хочу: поддержка конструкций
От: varnie  
Дата: 22.06.08 18:04
Оценка:
конечно, никто не отменял
{
  const Foo *pFoo = getFoo();
  if (pFoo){
    //работает далее с pFoo
  }
}
//здесь уже pFoo нет

а есть ли еще какие-нибудь способы?
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[2]: наверно я многого хочу: поддержка конструкций
От: varnie  
Дата: 22.06.08 18:40
Оценка:
Здравствуйте, _nn_, Вы писали:

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


__>На мой взгляд нужно просто избавляться от такого кода.

__>Лучше уже писать:
__>
__>Foo& f = getFoo();
__>// работаем с f
__>

__>А если getFoo проваливается выскакивает исключение

у меня подразумевается общий пример, взятие указателя и дальнейшие действия при условии что он валиден — не единственный предмет моего вопроса.
например, нам надо узнать есть ли в массиве число удовлетворяющее нашим условиям, и если оное имеется -- вывести его в консоль. т.е. если его нету, то мы не будем выбрасывать исключение, т.к. для нашей задачи это приемлемо, это некритично.
вот про задачи с подобным контекстом я и спрашиваю. хотел бы ограничить область видимости переменной, используемой для 5-6 строчек кода, используемой в определенной подзадаче. вот и все.
или это я такой педантичный и дотошный.
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[3]: наверно я многого хочу: поддержка конструкций
От: _nn_ www.nemerleweb.com
Дата: 22.06.08 19:39
Оценка:
Здравствуйте, varnie, Вы писали:

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


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


__>>На мой взгляд нужно просто избавляться от такого кода.

__>>Лучше уже писать:
__>>
__>>Foo& f = getFoo();
__>>// работаем с f
__>>

__>>А если getFoo проваливается выскакивает исключение

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

А зачем указатель ?

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


Тогда можно и так:
boost::optional<Foo*> getFoo()
{
 if(some_condition)
   return boost::optional<Foo*>(x);
 else
   return boost::optional<Foo*>();
}

void f(boost::optional<Foo*> foo)
{
 if(foo)
  // работаем
}

f(getFoo());


V>вот про задачи с подобным контекстом я и спрашиваю. хотел бы ограничить область видимости переменной, используемой для 5-6 строчек кода, используемой в определенной подзадаче. вот и все.

V>или это я такой педантичный и дотошный.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: наверно я многого хочу: поддержка конструкций
От: merk Россия  
Дата: 22.06.08 21:13
Оценка:
Здравствуйте, varnie, Вы писали:

V>здравствуйте все.


V>интересуюсь, почему язык поддерживает конструкции вида:

V>
V> if (const Foo *pFoo = getFoo()) {
V>   //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

V>но не поддерживает
V>
V> if ((const Foo *pFoo = getFoo()) == VALUE) {
V>    //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

V>на подобное натыкаюсь зачастую, и приходится вместо этого писать:
V>
V> const Foo *pFoo = getFoo();
V> if (pFoo){
V>    //работает далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

V>но немного не нравится, т.к. по логике сама переменная pFoo нам нужна только в теле блока if, а получается, что в моем последнем примере она будет доступна далее _после_ тела if. или я много хочу?
V>спасибо за комменты.

VC компилятор думает что открывающая скобка перед типом есть начало записи преобразования типа, вроде
(some_type)x, поскольку понять что там есть на самом деле, он может только после глубокого просмотра вперед..например если выражение сложное

(int x=f()+ff()+fff()... )

то разумеется он далеко вперед не смотрит и ругается.
если С++ делали не идиоты, такая конструкция вообще должна быть запрещена —
открывающая скобка перед именем типа, если это не преобразование.
Re: наверно я многого хочу: поддержка конструкций
От: Юрий Жмеренецкий ICQ 380412032
Дата: 23.06.08 01:14
Оценка:
Здравствуйте, varnie, Вы писали:

V>здравствуйте все.


V>интересуюсь, почему язык поддерживает конструкции вида:

V>
V> if (const Foo *pFoo = getFoo()) {
V>   //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет
V>


V>но не поддерживает

V>
V> if ((const Foo *pFoo = getFoo()) == VALUE) {
V>    //работаем далее с pFoo
V> }
V> //здесь уже pFoo нет


Грамматика языка говорит о том, что condition в if-statement может представлять собой один из двух вариантов:

condition:
  expression
  typespecifier seq declarator = assignment expression


'(const Foo *pFoo = getFoo()) == VALUE' — это expression, а объявления переменных в нем недопустимы.


PS: Так тоже можно:
if(int i = f())
{
 //...
}
else
{
  i = 0;  
}
Re[2]: наверно я многого хочу: поддержка конструкций
От: Юрий Жмеренецкий ICQ 380412032
Дата: 23.06.08 01:27
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>'(const Foo *pFoo = getFoo()) == VALUE' — это expression, а объявления переменных в нем недопустимы.

Точнее не expression, а нечто похожее.
Re[2]: наверно я многого хочу: поддержка конструкций
От: jazzer Россия Skype: enerjazzer
Дата: 23.06.08 02:36
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Возможно, попытки применить этот синтаксис как-то по другому сродни попытке использовать for не для инициализации-проверки-инкремента итератора.


Он предназначен для проверки указателей, которые откуда-то возвращаются и с которыми дальше можно работать только если они ненулевые, а это — один из самых распространенных сценариев, и даункастинг тут — о малое.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: наверно я многого хочу: поддержка конструкций
От: jazzer Россия Skype: enerjazzer
Дата: 23.06.08 02:54
Оценка:
Здравствуйте, varnie, Вы писали:

V>но немного не нравится, т.к. по логике сама переменная pFoo нам нужна только в теле блока if, а получается, что в моем последнем примере она будет доступна далее _после_ тела if. или я много хочу?


Многого. Подумай не тему времени жизни pFoo с учетом того, где и как он объявлен, и где и как ты его объявляешь.

Плюс твой пример можно обобщить: ведь необязательно мы хотим сравнивать, возможно, мы захотим позвать метод и проверить то, что он вернет:
if (Object& o = get_object(); o.is_valid() )
{
  // работаем с o
}

или родить несколько объектов и проверять сложные условия:
if (Object1& o1 = get_object1(); Object2* o2 = get_object2(); o1.field == o2->field )
{
  // работаем с o1, o2
}

ну а отсюда и до полноценной программы внутри if недалеко


Хотя, конечно, можно было бы изменить синтаксис как-то так:
if ( declaration-list_opt; expression_list_opt ) statement;

c соответсвующим временем жизни всех объявленных переменных.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Вечный цикл? :) (-)
От: Erop Россия  
Дата: 24.06.08 20:58
Оценка:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: наверно я многого хочу: поддержка конструкций
От: _Jane_ Украина  
Дата: 25.06.08 13:26
Оценка:
Здравствуйте, varnie, Вы писали:

V>на подобное натыкаюсь зачастую, и приходится вместо этого писать:

V>
V> const Foo *pFoo = getFoo();
V> if (pFoo){
V>    //работает далее с pFoo
V> }
V> //здесь уже pFoo нет
V>

V>но немного не нравится, т.к. по логике сама переменная pFoo нам нужна только в теле блока if, а получается, что в моем последнем примере она будет доступна далее _после_ тела if. или я много хочу?

Некоторые особо умные компиляторы и так делают такие переменные доступными после тела if

V>спасибо за комменты.
Jane
Re[3]: наверно я многого хочу: поддержка конструкций
От: Roman Odaisky Украина  
Дата: 25.06.08 13:48
Оценка:
Здравствуйте, Sergey, Вы писали:

>> Чего на самом деле не хватает, так это using, как в C#:

>> using(X x = getX())
>> if(i_like(x) && x.is_very_nice())
>> {
>> . . .
>> }
>> В C++ это можно сделать только через for:
>> http://www.rsdn.ru/forum/message/2397489.1.aspx
Автор: Roman Odaisky
Дата: 07.03.07


S>А чем это лучше обычных фигурных скобок?


Тем, что можно использовать в макросах. Например:
#define DOUBLE_FOR(decl1, decl2, cond1, cond2, upd1, upd2) \
    using(decl1) \
    for(decl2; (cond1) && (cond2); (upd1), (upd2))

Иногда в макросах нужно вставить несколько объявлений, а for не подходит из-за break/continue, и фигурные скобки не подходят из-за того, что закрывающую скобку ставить некому.

И вообще, код вроде
doSomething();

using(Lock lock(mutex))
{
    doSomethingElse();
}

выглядит, по-моему, естественнее, чем фигурные скобки из ниоткуда:
doSomething();

{
    Lock lock(mutex);

    doSomethingElse();
}
До последнего не верил в пирамиду Лебедева.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.