Здравствуйте, PlusMyTwitterFace, Вы писали:
PMT>Почему данный код выводит именно 1?
PMT>PMT>#include <iostream>
PMT>int main()
PMT>{
PMT> std::cout << []{ return 0; } << '\n';
PMT>}
PMT>
PMT>http://liveworkspace.org/code/cb8b23a0336499531320c422d53999b0
PMT>Почему не вызывается лямбда мне понятно, не могу только никак понять, почему в stdout попадает именно 1. Или это implementation-defined в зависимости от того, как в компиляторе реализованы лямбды? Так, вроде как, лямбды в большинстве случаев представляются как объекты-функторы, а для применения к ним operator<< его ещё перегрузить надо. Или срабатывает преобразование к указателю void*? В общем, что говорит стандарт по данному поводу?
Сначала происходит преобразование объекта в указатель на функцию, а затем этот указатель на функцию преобразуется в тип
void *, и для него вызывается оператор
operator <<( const void * ).
Если вы измените ваш пример, добавив захватываемую переменную, то код уже не должен компилироваться, так как для лямбда-выражений, имеющих захватываемые переменные, оператор-функция преобразования в указатель на функцию не создается. Рассмотрите следующий код
#include <iostream>
int main()
{
int x = 0;
auto lm = [x] { return x; };
std::cout << lm << std::endl;
}
Компилятор для этого кода должен сгенерировать ошибку компиляции, так как для объекта
lm, который представляет собой объект лямбда-выражения, не определен оператор
operator <<.
С другой стороны, вы можете скомпилировать следующий код
#include <iostream>
int main()
{
int ( *fn )( void ) = [] { return 0; };
std::cout << fn << std::endl;
}
Этот код даст тот же самый результат, который вы получили для своего собственного исходного примера. Только в моем примере я явно преобразую лямбда-выражение в указатель на функцию.
Поэтому значение, равное 1, для этого адреса — это особенность того компилятора, который вы используете. Другие компиляторы моогут выдать совершенно другое значение для адреса указателя на функцию для лямбда-выражения.