наверно я многого хочу: поддержка конструкций
От: 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[2]: наверно я многого хочу: поддержка конструкций
От: varnie  
Дата: 22.06.08 18:04
Оценка:
конечно, никто не отменял
{
  const Foo *pFoo = getFoo();
  if (pFoo){
    //работает далее с pFoo
  }
}
//здесь уже pFoo нет

а есть ли еще какие-нибудь способы?
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
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: наверно я многого хочу: поддержка конструкций
От: 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[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: наверно я многого хочу: поддержка конструкций
От: 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: наверно я многого хочу: поддержка конструкций
От: Юрий Жмеренецкий 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: наверно я многого хочу: поддержка конструкций
От: Кодт Россия  
Дата: 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]: наверно я многого хочу: поддержка конструкций
От: 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[3]: Вечный цикл? :) (-)
От: Erop Россия  
Дата: 24.06.08 20:58
Оценка:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
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]: наверно я многого хочу: поддержка конструкций
От: 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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.