Сам объект типа класса не может быть преобразован к типу bool, если в классе нет соответствующей оператор-функции преобразования к типу bool. Это наглядно демонстрирует пример, которые я уже приводил ранее
int main()
{
struct A {} a;
if ( a );
}
Здесь условие в предложенит if требует преобразования выражения в тип bool, которое не происходит, так как в классе нет функции преобразования. Компилятор должен ивыдать сообщение об ошибке.
Поэтому, возвращаясь к исходному примеру темы, в любом случае сначала происходит преобразование лямбда-выражения в указатель на функцию. Я уже приводил другой пример, когда если для лямбда-выражения такой опреатор-функции не существует по причине, что лямбда-выражение захватывает локальную переменную, то код вообще не будет компилироваться.
Следовательно очевидно, что происходит преобразование в указатель на функцию для лямбда-выражения.
Теперь осталось разобраться, какой оператор вывода вызывается, либо для bool, либо для const void *.
Это зависит от того, во что преобразуется неявно указатель на функцию: либо в bool, либо в const void *.
Если он преобразуется в тип bool, то имеет место баг компилятора MS VC++.
С>>Посмотрите в режиме отладки, какой оператор вывода у вас будет использоваться, и сообщите всем нам. Договорились?
_>std::basic_ostream<char,struct std::char_traits<char> > & std::basic_ostream<char,struct std::char_traits<char> >::operator<<(bool)
Значит имеет место баг компилятора MS VC++.
Здесь я настаивал на том, что происходит преобразование лямбда-выражения в указатель на функцию.
Если такого преобразования для лямбда-выражения нет в сиду того, что лямбда-выражение захватывает локальную перменную, то будет выдана ошибка компиляции.
Далее уже стоит технический вопрос, какой оператор вывода для преобразованного лямбда-выражения в указатель на функцию должен быть выбран.
Я исходил из положения стандарта, описанного в праграфе 2 раздела 4.10, в котором говорится, что
"2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points..."
Возможно я был не прав, и тут имеет место преобразваоние указателя к bool.
"2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points..."
Может быть дело в том, что в нашем случае T не является object type?
Balthasar:
B>"2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points..."
B>Может быть дело в том, что в нашем случае T не является object type?
Разумеется — см. 3.9/8:
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.
P.S.
VC++ 10 с отключенными расширениями (/Za) даёт правильный результат.
Здравствуйте, Masterkent, Вы писали:
M>Balthasar:
B>>"2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points..."
B>>Может быть дело в том, что в нашем случае T не является object type?
M>Разумеется — см. 3.9/8: M>
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.
M>P.S. M>VC++ 10 с отключенными расширениями (/Za) даёт правильный результат.
Да я об этом и говорил, просто выразил в форме наводящего вопроса.
Здравствуйте, Balthasar, Вы писали:
B>"2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points..."
B>Может быть дело в том, что в нашем случае T не является object type?
Согласен. Но в любом случае вопрос связан с тем, может ли лямбда-выражение быть преобразовано к указателю на функцию, и уже затем лишь выбирается перегруженный оператор вывода для указателя на функцию. Если лямбда-выражение не имеет преобразования в указатель на функцию, как в случае, если она имеет не пустое capture, то будет ошибка компиляции.
Здравствуйте, Сыроежка, Вы писали:
С>Поэтому значение, равное 1, для этого адреса — это особенность того компилятора, который вы используете. Другие компиляторы моогут выдать совершенно другое значение для адреса указателя на функцию для лямбда-выражения.
И что, ты правда веришь, что у ТС такой хитрый компилятор, в котором адрес кода может быть 1?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Сыроежка, Вы писали:
С>Я вам советую проверить все те примеры кода, который я привел в своем сообщении, особенно тот пример, где имеет место явное преобразваоние лямбда объекта в указатель на функцию, а также пример, где имеется захватываемая переменная.
Особенно рекомендую почитать предупрждениея компилятора:
source.cpp:9:17: warning: the address of 'void g()' will always evaluate as 'true' [-Waddress]
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Сыроежка, Вы писали:
С>Сам объект типа класса не может быть преобразован к типу bool, если в классе нет соответствующей оператор-функции преобразования к типу bool. Это наглядно демонстрирует пример, которые я уже приводил ранее
Тоже лажа!
С>
С>int main()
С>{
С> struct A {} a;
С> if ( a );
С>}
С>
Вот правильный пример. Попробуй найти там "оператор-функцию преобразования к типу bool. " (с)...
С>Это зависит от того, во что преобразуется неявно указатель на функцию: либо в bool, либо в const void *. С>Если он преобразуется в тип bool, то имеет место баг компилятора MS VC++.
IMHO, в данном случае баг в твоём понимании стандарта. Указателди на функции к bool как раз могут, а к void* нет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Сыроежка, Вы писали:
С>>Сам объект типа класса не может быть преобразован к типу bool, если в классе нет соответствующей оператор-функции преобразования к типу bool. Это наглядно демонстрирует пример, которые я уже приводил ранее
E>Тоже лажа!
С>>
С>>int main()
С>>{
С>> struct A {} a;
С>> if ( a );
С>>}
С>>
E>Вот правильный пример. Попробуй найти там "оператор-функцию преобразования к типу bool. " (с)...
У вас каша в голове. Вы просто не понимаете, что вы сами пишите в коде. В вашем примере не объект преобразуется к типу bool, а указатель на функцию преобразуется к типу bool. Указатель на функцию и объект класса — это разные понятия. Никакого преобразования объекта класса в тип bool в вашем примере нет.
Нет такого неявного преобразования из объекта класса в тип bool.
Так что ваш пример к не имеет отношения к преобразования объекта класса к типу bool и является совершенно некорректным в контексте этого преобразваония. Корректный пример я вам показал, который как раз и демонстрирует, что нет такого неявного преобразования из объекта класса в тип bool.
Сыроежка:
E>>Вот правильный пример. Попробуй найти там "оператор-функцию преобразования к типу bool. " (с)...
С>У вас каша в голове. Вы просто не понимаете, что вы сами пишите в коде. В вашем примере не объект преобразуется к типу bool, а указатель на функцию преобразуется к типу bool. Указатель на функцию и объект класса — это разные понятия. Никакого преобразования объекта класса в тип bool в вашем примере нет. С>Нет такого неявного преобразования из объекта класса в тип bool.
Это как раз у тебя каша в голове.
4/3:
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t (8.5).
Выражение может быть преобразовано к некоему типу последовательностью преобразований, состоящей из более одного преобразования. Например, тут
#include <iostream>
struct Base {};
struct Derived : Base {};
typedef Derived Array[1];
Array array;
struct Source
{
operator Array &() const { return array; }
};
int main()
{
const Base *p = Source();
}
происходит сразу 4 неявных преобразования:
prvalue of type Source -> lvalue of type Derived[1] (user-defined conversion) -> prvalue of type Derived * (standard array-to-pointer conversion) -> Base * (standard pointer conversion) -> const Base * (standard qualification conversion).
И вполне можно сказать, что выражение Source() может быть преобразовано к const Base *.
О том, что в исходном примере лямбда преобразуется в bool ровно одним непосредственным преобразованием, тут никто не говорил.
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
E>>>Вот правильный пример. Попробуй найти там "оператор-функцию преобразования к типу bool. " (с)...
С>>У вас каша в голове. Вы просто не понимаете, что вы сами пишите в коде. В вашем примере не объект преобразуется к типу bool, а указатель на функцию преобразуется к типу bool. Указатель на функцию и объект класса — это разные понятия. Никакого преобразования объекта класса в тип bool в вашем примере нет. С>>Нет такого неявного преобразования из объекта класса в тип bool.
M>Это как раз у тебя каша в голове.
M>4/3: M>
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t (8.5).
M>Выражение может быть преобразовано к некоему типу последовательностью преобразований, состоящей из более одного преобразования. Например, тут
M>
M>происходит сразу 4 неявных преобразования:
M>prvalue of type Source -> lvalue of type Derived[1] (user-defined conversion) -> prvalue of type Derived * (standard array-to-pointer conversion) -> Base * (standard pointer conversion) -> const Base * (standard qualification conversion).
M>И вполне можно сказать, что выражение Source() может быть преобразовано к const Base *.
M>О том, что в исходном примере лямбда преобразуется в bool ровно одним непосредственным преобразованием, тут никто не говорил.
Я говорил о том, что нет неявного стандартного преобразования объекта типа класса в тип bool, и продемонстрировал это конкретным примером, указав при этом, что нужна в классе оператор-функция преобразваония типов.
Так что не надо наводить тень на плетень. Вы сейчас дискуссируете сами с собой, так как ничего не опровергли. Во-первых, вы ничем не опровергли мой пример кода, демонстрирующий мое высказывание. Во-вторых, вы ввели функцию преобразваония в класс, о чем я с самого начала говорил..
Сыроежка:
С>Я говорил о том, что нет неявного стандартного преобразования объекта типа класса в тип bool
Цитирую: Сам объект типа класса не может быть преобразован к типу bool, если в классе нет соответствующей оператор-функции преобразования к типу bool.
Здесь ни слова не сказано о том, что речь идёт конкретно про стандартные преобразования.
С>Вы сейчас дискуссируете сами с собой
Это ты намекаешь на свою невменяемость и бесполезность ведения дискуссий с тобой? Да я-то уже давно это понял, вот иногда и пытаюсь помочь другим это осознать.
По теме тут уже давно расписали что куда и в какой последовательности преобразуется.
С>Во-первых, вы ничем не опровергли мой пример кода, демонстрирующий мое высказывание.
Что означает "опровергнуть пример кода"? Что это за действие такое?
С>Во-вторых, вы ввели функцию преобразваония в класс, о чем я с самого начала говорил..
Давай-ка я напомню шибко башковитому парню, о чём он говорил с самого начала:
Сначала происходит преобразование объекта в указатель на функцию, а затем этот указатель на функцию преобразуется в тип void *, и для него вызывается оператор operator <<( const void * ).
О том, что подобная фигня имеет место лишь применительно к конкретно взятому компилятору с конкретными настройками (нестандартные расширения включены) и что такое поведение не является соответствующим стандарту, автор процитированного, видимо, не знал, не так ли?
U>выше уже отметили, что лямбда сконвертировалась в bool, и вызывался соответствующий operator<<(bool)
То, что вы раньше написали, совершеннно не корректно. С чего это, вдруг, лямбда объект должен преобразовываться к типу bool?!
Высказывание uzhas-а "лямбда сконвертировалась в bool" корректно: лямбда без lambda-capture может преобразовываться в bool двумя последовательными неявными преобразованиями, что и произошло в случае автора темы.