Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 05:24
Оценка:
Здравствуйте,все!

Очень странно...

VC6 поддерживает

if( int ok( 123 ) )
{
//...
}

а VC7 — ругается...

Это у всех VC7, или только в моей версии ?

(номер версии не помню, но одна из начальных 7)

Более реальный пример

if( PSTR pName( GetName() ) )
{
// do use pName
}

// не засоряется "scope"

Помогите ответом, пожалуйста...
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re: Инициализация в условии
От: Сергей Зизев Украина  
Дата: 03.08.05 06:12
Оценка: -2
Здравствуйте, SergeCpp, Вы писали:

SC>Здравствуйте,все!


SC>Очень странно...


SC>VC6 поддерживает

Ошибка в VC6

SC>if( int ok( 123 ) )

SC>{
SC> //...
SC>}

Выражение int ok( 123 ) есть ни что иное как определние функции, оно не может стоят в условии оператора if.
Условием оператора if может быть либо выражение либо декларатор, поэтому если Вы хотите внутри блока if объявить переменную ok и присвоить ей значение, то синтаксис должен быть такой:

if (int ok = 123) 
{
  std::cout << ok << std::endl; 
}
Re[2]: Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 06:24
Оценка:
Здравствуйте, Сергей Зизев, Вы писали:

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


SC>>Здравствуйте,все!


SC>>Очень странно...


SC>>VC6 поддерживает

СЗ>Ошибка в VC6

SC>>if( int ok( 123 ) )

SC>>{
SC>> //...
SC>>}

СЗ>Выражение int ok( 123 ) есть ни что иное как определние функции, оно не может стоят в условии оператора if.

СЗ>Условием оператора if может быть либо выражение либо декларатор, поэтому если Вы хотите внутри блока if объявить переменную ok и присвоить ей значение, то синтаксис должен быть такой:

СЗ>
СЗ>if (int ok = 123) 
СЗ>{
СЗ>  std::cout << ok << std::endl; 
СЗ>}
СЗ>



Я не согласен с Вами.

"int ok( 123 )" есть объявление объекта типа "int" с именем "ok"...

Дело НЕ в int.

class SomeType
{
//... где-то тут ЕСТЬ конструктор с параметром типа "int"

operator bool(){ return true; } // например
};

if( SomeType ok( 123 ) ) // конструируем из 123 и проверяем "не отходя от кассы"
{
// do use "ok"
}

Это РАБОТАЕТ в VC6
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re[3]: Инициализация в условии
От: Сергей Зизев Украина  
Дата: 03.08.05 07:18
Оценка: -2
Здравствуйте, SergeCpp, Вы писали:

[skipped...]

SC>Я не согласен с Вами.


SC>"int ok( 123 )" есть объявление объекта типа "int" с именем "ok"...

Нет, это не так, посмотри внимательно в 8.2/1, там есть почти такой же пример. В C++ данное выражение интерпретируется как объявление функции
с именем ok, возвращающей int и принимающей целое (тоже int). Существует надежда, что комитет когда-нибудь это исправит

SC>Дело НЕ в int.


SC>class SomeType

SC>{
SC>//... где-то тут ЕСТЬ конструктор с параметром типа "int"

SC>operator bool(){ return true; } // например

SC>};

SC>if( SomeType ok( 123 ) ) // конструируем из 123 и проверяем "не отходя от кассы"

Здесь аналогично, объявлена функция с именем ok, возвращающая SomeType и принимающая целое.

SC>Это РАБОТАЕТ в VC6

Это ошибка в VC6, в VC7.1 это подлечили
Re[4]: Инициализация в условии
От: CrystaX Россия https://crystax.me/
Дата: 03.08.05 07:35
Оценка: +1
Здравствуйте, Сергей Зизев, Вы писали:

SC>>Я не согласен с Вами.


SC>>"int ok( 123 )" есть объявление объекта типа "int" с именем "ok"...

СЗ>Нет, это не так, посмотри внимательно в 8.2/1, там есть почти такой же пример. В C++ данное выражение интерпретируется как объявление функции
СЗ>с именем ok, возвращающей int и принимающей целое (тоже int). Существует надежда, что комитет когда-нибудь это исправит

Неверно. В объявлении функции не может быть целочисленного значения. Может быть только список формальных параметров. 123 не является формальным параметром. Для сравнения:

#include <iostream>

int main()
{
    int ok(123);

    std::cout << ok << std::endl; // Все хорошо, ok - это целочисленная переменная, ее значение 123

    return 0;
}


#include <iostream>

int main()
{
    size_t n = 1;
    int ok(int(n));

    std::cout << ok << std::endl; // А вот здесь уже неверно.
    // ok - это объявление функции, возвращающей int и принимающей также int.
    // Выражение int(n) по синтаксису является списком формальных параметров.

    return 0;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[5]: Инициализация в условии
От: Сергей Зизев Украина  
Дата: 03.08.05 08:38
Оценка:
Hello, CrystaX!
You wrote on Wed, 03 Aug 2005 07:35:53 GMT:

C> Здравствуйте, Сергей Зизев, Вы писали:


SC>>> Я не согласен с Вами.


[skipped...]

C> Неверно. В объявлении функции не может быть целочисленного значения.

Да, я был не прав.
C> Может быть только список формальных параметров. 123 не является
C> формальным параметром. Для сравнения:

Тогда почему же, все таки компилятор пытается интерпретировать выражение:
if (SomeType ok (123))
//...
как объявление функции ? Возможно по тому, что не может привести его к типу
bool ? Так оно и не приводимо к bool.

[skipped...]

With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com
Posted via RSDN NNTP Server 1.9
Re[6]: Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 08:48
Оценка:
Здравствуйте, Сергей Зизев, Вы писали:

[skipped...]

СЗ>как объявление функции ? Возможно по тому, что не может привести его к типу

СЗ>bool ? Так оно и не приводимо к bool.

СЗ>[skipped...]


СЗ>With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com


Оператор "bool" был упомянут мною именно
для предотвращения "...Так оно и не приводимо к bool..."

Приводимо.

class SomeType
{
//... где-то тут ЕСТЬ конструктор с параметром типа "int"

operator bool(){ return true; } // <<< например
};

SomeType ok ( 123 );
bool val( ok ); // здесь вызывается SomeType::bool()...
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re: Инициализация в условии
От: Lorenzo_LAMAS  
Дата: 03.08.05 08:59
Оценка:
Вот как определен if в грамматике

6.4 Selection statements [stmt.select]
1 Selection statements choose one of several flows of control.
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq declarator = assignment-expression//т.е. нужен именно такой инициализатор = что-то

Of course, the code must be complete enough to compile and link.
Re[7]: Инициализация в условии
От: Сергей Зизев Украина  
Дата: 03.08.05 09:11
Оценка:
Hello, SergeCpp!
You wrote on Wed, 03 Aug 2005 08:48:12 GMT:

S> Здравствуйте, Сергей Зизев, Вы писали:


S> [skipped...]


СЗ>> как объявление функции ? Возможно по тому, что не может привести его к

СЗ>> типу bool ? Так оно и не приводимо к bool.

СЗ>> [skipped...]


СЗ>> With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com


S> Оператор "bool" был упомянут мною именно

S> для предотвращения "...Так оно и не приводимо к bool..."

S> Приводимо.


S> class SomeType

S> {
S> //... где-то тут ЕСТЬ конструктор с параметром типа "int"

S> operator bool(){ return true; } // <<< например

S> };

S> SomeType ok ( 123 );

S> bool val( ok ); // здесь вызывается SomeType::bool()...
Да это все понятно, но речь идет о контексте оператора if (о его condition),
и получается что в данном контексте компилятор не может даже проверить
наличие твоего оператора bool у выражения SomeType ok ( 123 ), ввиду чего
пытается (это я так думаю) распарсить его как объявление функции, что
соответственно приводит к ошибке. Что бы все было ок, поставь равно, как я
писал в первом посте, тогда и твой оператор вызовется.


With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com
Posted via RSDN NNTP Server 1.9
Re[8]: Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 09:37
Оценка:
Здравствуйте, Сергей Зизев, Вы писали:

...

СЗ>соответственно приводит к ошибке. Что бы все было ок, поставь равно, как я

СЗ>писал в первом посте, тогда и твой оператор вызовется.


СЗ>With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com


SomeType a( 1 );

SomeType b ( a ); // семантика этих двух строк
SomeType c = a; // сильно отличается

// не хочу цитировать Dr. Stroustrup, почитайте,
// там это детально объяснено

Всё же повторю уточнённый вопрос

if( int ok( 123 ) ) // проходит в самой новой версии VC7 ?
{
}
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re[9]: Инициализация в условии
От: Lorenzo_LAMAS  
Дата: 03.08.05 09:45
Оценка:
SC>SomeType a( 1 );

SC>SomeType b ( a ); // семантика этих двух строк

SC>SomeType c = a; // сильно отличается

Неверно. При таких типах объектов она идентична.
Of course, the code must be complete enough to compile and link.
Re[9]: Инициализация в условии
От: stasan  
Дата: 03.08.05 10:01
Оценка:
S> SomeType a( 1 );

S> SomeType b ( a ); // семантика этих двух строк

S> SomeType c = a; // сильно отличается

И там и там вызывается copy constructor. В чем разница?

S> // не хочу цитировать Dr. Stroustrup, почитайте,

S> // там это детально объяснено

Возможно вы путаете ситуацию с неявным созданием временного объекта и последующего присваивания с помощью оператора =. Здесь не этот случай.

S> Всё же повторю уточнённый вопрос


S>if( int ok( 123 ) ) // проходит в самой новой версии VC7 ?

S>{
S>}

Нет, на правильных компиляторах это работать не должно. Вам уже привели выдержку из стандарта. Используйте

if( int ok = 123 ) {
}

if( SomeType ok = 123 ) {
}


и все будет хорошо. Для SomeType будет вызываться тот же самый конструктор, который принимает int.

--
Stas
Posted via RSDN NNTP Server 1.9
Re[10]: Инициализация в условии
От: Lorenzo_LAMAS  
Дата: 03.08.05 10:15
Оценка: 2 (1)
Ну, разница тут все же есть.
Есть прямая инициализация Т а1(а); и инициализация копированием Т а1 = а;
Вот что говорит стандарт

— If the destination type is a (possibly cv-qualified) class type:
...
If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version
of the source type is the same class as, or a derived class of, the class of the destination, constructors
are considered. The applicable constructors are enumerated (13.3.1.3), and the best one is
chosen through overload resolution (13.3). The constructor so selected is called to initialize the
object, with the initializer expression(s) as its argument(s).
If no constructor applies, or the overload
resolution is ambiguous, the initialization is ill-formed.
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that
can convert from the source type to the destination type or (when a conversion function is used) to a
derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through
overload resolution (13.3). If the conversion cannot be done or is ambiguous, the initialization is
ill-formed. The function selected is called with the initializer expression as its argument; if the function
is a constructor, the call initializes a temporary of the destination type. The result of the call
(which is the temporary for the constructor case) is then used to direct-initialize, according to the
rules above, the object that is the destination of the copy-initialization.
In certain cases, an implementation
is permitted to eliminate the copying inherent in this direct-initialization by constructing
the intermediate result directly into the object being initialized; see 12.2, 12.8.

Of course, the code must be complete enough to compile and link.
Re[9]: Инициализация в условии
От: Сергей Зизев Украина  
Дата: 03.08.05 10:34
Оценка:
Hello, SergeCpp!
You wrote on Wed, 03 Aug 2005 09:37:47 GMT:

S> Здравствуйте, Сергей Зизев, Вы писали:


S> ...


СЗ>> соответственно приводит к ошибке. Что бы все было ок, поставь равно,

СЗ>> как я писал в первом посте, тогда и твой оператор вызовется.

СЗ>> With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com


S> SomeType a( 1 );


S> SomeType b ( a ); // семантика этих двух строк

S> SomeType c = a; // сильно отличается

S> // не хочу цитировать Dr. Stroustrup, почитайте,

S> // там это детально объяснено
Причем здесь Страуструп к семантике оператора if, тем более отличия
direct-initialization от copy-initialization здесь вообще не причем.

S> Всё же повторю уточнённый вопрос


S> if( int ok( 123 ) ) // проходит в самой новой версии VC7 ?

S> {
S> }
Данный фрагмент кода неверен и он не проходит в VC7.1

With best regards, Sergey Zizyov. E-mail: ziserg@despammed.com
Posted via RSDN NNTP Server 1.9
Re[10]: Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 10:45
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

SC>>SomeType a( 1 );


SC>>SomeType b ( a ); // семантика этих двух строк

SC>>SomeType c = a; // сильно отличается

L_L>Неверно. При таких типах объектов она идентична.


К сожалению, НЕ идентична...
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re[11]: Инициализация в условии
От: Lorenzo_LAMAS  
Дата: 03.08.05 10:49
Оценка:
Здравствуйте, SergeCpp, Вы писали:

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


SC>>>SomeType a( 1 );


SC>>>SomeType b ( a ); // семантика этих двух строк

SC>>>SomeType c = a; // сильно отличается

L_L>>Неверно. При таких типах объектов она идентична.


SC>К сожалению, НЕ идентична...

Если вас не затруднит, посмотрите для начала приведенную мною в этом обсуждении цитату из стандарта, после этого, продолжим (если будет охота)
Of course, the code must be complete enough to compile and link.
Re[11]: Инициализация в условии
От: stasan  
Дата: 03.08.05 11:45
Оценка:

Ну, разница тут все же есть.


Хмм, вы имеете ввиду то, что в первом случае используется direct-initalization, а во втором copy-initialization? Это конечно.
Но в данном контексте разницы нет, т.к. оба случая подпадают под пункт 1 приведенной из стандарта цитаты. Т.е. реально в
обоих случаях напрямую вызывается copy constructor, и разницы никакой нет. Или я что-то упустил?

Или вы имели ввиду следующий код:

if( SomeType ok = 123 ) {
}

?

Здесь конечно никто не гарантирует, что не будет вызываться copy-constructor, но я об этом и не говорил. Я лишь сказал, что будет вызван
тот же самый конструктор, принимающий int (класс SomeType из оригинального поста или где-то рядом). Да, возможно он будет вызван как
conversion constructor.

Или вы о чем-то другом?

PS. в любом случае, спасибо за цитату.

Offtopic:
Кстати. У меня последний стандарт от 1998 года. Есть более свежий? Если да, то где взять?

И парни, отличный форум. Кто бы мог подумать, что есть что-либо подобное в рунете.
The best one!

--
Stas
Posted via RSDN NNTP Server 1.9
Re[12]: Инициализация в условии
От: Lorenzo_LAMAS  
Дата: 03.08.05 11:54
Оценка:
Здравствуйте, stasan, Вы писали:

S>

S>Ну, разница тут все же есть.


S>Хмм, вы имеете ввиду то, что в первом случае используется direct-initalization, а во втором copy-initialization? Это конечно.


я уже забыл, чего мне показалось, вроде у меня вызвали подозрения слова про оператор присваивания
и темпорари (но если вы говорили не о Т а = 1, где нет присваивания, то все ОК).

S>Но в данном контексте разницы нет, т.к. оба случая подпадают под пункт 1 приведенной из стандарта цитаты. Т.е. реально в

S>обоих случаях напрямую вызывается copy constructor, и разницы никакой нет. Или я что-то упустил?

да, тут пункт 1.

S>PS. в любом случае, спасибо за цитату.


S>Offtopic:

S>Кстати. У меня последний стандарт от 1998 года. Есть более свежий? Если да, то где взять?

Такие вопросы не приветствуются
давай мыло
Of course, the code must be complete enough to compile and link.
Re[12]: Инициализация в условии
От: SergeCpp Россия http://zoozahita.ru
Дата: 03.08.05 12:06
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

...

SC>>К сожалению, НЕ идентична...

L_L>Если вас не затруднит, посмотрите для начала приведенную мною в этом обсуждении цитату из стандарта, после этого, продолжим (если будет охота)

Да, признаю, в этом случае, вероятно, так
(не пишу "наверняка так", потому что мне нужно думать —
ну торможу помаленьку...)

Но самое главное, из за чего мой вопрос возник — у меня НЕ "same class"...

"...if the function is a constructor,
the call initializes a temporary of the destination type..."

Вот в чём мой страх, несмотря на

"...In certain cases, an implementation is permitted to eliminate
the copying inherent in this direct-initialization by constructing
the intermediate result directly into the object being initialized..."

С уважением, Сергей Смирнов

P.S. Ничего личного — это ТЕХНИЧЕСКИЙ вопрос (НЕ мой выпендрёж)
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re[5]: Инициализация в условии
От: jazzer Россия Skype: enerjazzer
Дата: 03.08.05 12:14
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>
CX>#include <iostream>

CX>int main()
CX>{
CX>    size_t n = 1;
CX>    int ok(int(n));

CX>    std::cout << ok << std::endl; // А вот здесь уже неверно.
CX>    // ok - это объявление функции, возвращающей int и принимающей также int.
CX>    // Выражение int(n) по синтаксису является списком формальных параметров.

CX>    return 0;
CX>}
CX>


а чего ж неверного :) распечатается адрес функции :)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.