lambda to pointer to function conversion
От: Nikita.Trophimov  
Дата: 01.03.13 04:15
Оценка:
int main()
{
   void (*fp)() = [&]{}; // Ok
}


int main()
{
   int foo;
   void (*fp)() = [&]{ foo = 0; }; // error: cannot convert 'main()::<lambda()>' to 'void (*)()' in initialization
}


int main()
{
   int foo;
   void (*fp)() = [&foo]{}; // error: cannot convert 'main()::<lambda()>' to 'void (*)()' in initialization
}


gcc 4.7.2.

По-моему, первый кусок кода также не должен был скомпилироваться.

ISO/IEC 14882:2011

5.1.2 Lambda expressions [expr.prim.lambda]

6 The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const
conversion function to pointer to function having the same parameter and return types as the closure type’s
function call operator.


Баг gcc?
Re: lambda to pointer to function conversion
От: watch-maker  
Дата: 01.03.13 10:18
Оценка:
Здравствуйте, Nikita.Trophimov, Вы писали:

NT>По-моему, первый кусок кода также не должен был скомпилироваться.

NT>

NT>6 The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const
NT>conversion function to pointer to function having the same parameter and return types as the closure type’s
NT>function call operator.


Это же не причина. Из условия «все А обладают свойством Б» не следует, что свойством Б не могут обладать какие-либо третьи объекты.
Только этот пункт не запрещает приводить любые лямбды к указателям на функции, он лишь описывает для каких лямбд это приведение будет гарантированно успешным.

NT>Баг gcc?

А ещё такой же «баг» есть в msvc и в intel c++. Разве что clang решил отличится.

По-моему, тут нет запрета от стандарта. Так что на полноценный баг это не тянет. Но так как и гарантий тоже нет, то пользоваться этой особенностью не следует.
Re: lambda to pointer to function conversion
От: GreyMan  
Дата: 01.03.13 17:22
Оценка:
Здравствуйте, Nikita.Trophimov, Вы писали:

NT>
NT>int main()
NT>{
NT>   void (*fp)() = [&]{}; // Ok
NT>}
NT>


Попробуйте в тело лямбды вставить код, обращающийся к захваченным переменным. Сразу все станет на свои места.
Re[2]: lambda to pointer to function conversion
От: Nikita.Trophimov  
Дата: 01.03.13 20:02
Оценка:
WM>Это же не причина. Из условия «все А обладают свойством Б» не следует, что свойством Б не могут обладать какие-либо третьи объекты.
WM>Только этот пункт не запрещает приводить любые лямбды к указателям на функции, он лишь описывает для каких лямбд это приведение будет гарантированно успешным.

The closure type for a lambda-expression with no lambda-capture


Теперь смотрим на наш код:

int main()
{
   void (*fp)() = [&]{};
}


lambda-capture присутствует, однако код компилируется.
Re[2]: lambda to pointer to function conversion
От: Nikita.Trophimov  
Дата: 01.03.13 20:03
Оценка:
GM>Попробуйте в тело лямбды вставить код, обращающийся к захваченным переменным. Сразу все станет на свои места.

Я об этом как раз и написал уже в первом сообщении этой темы.

int main()
{
   int foo;
   void (*fp)() = [&]{ foo = 0; }; // error: cannot convert 'main()::<lambda()>' to 'void (*)()' in initialization
}
Re[3]: lambda to pointer to function conversion
От: watch-maker  
Дата: 01.03.13 20:12
Оценка:
Здравствуйте, Nikita.Trophimov, Вы писали:

WM>>Это же не причина. Из условия «все А обладают свойством Б» не следует, что свойством Б не могут обладать какие-либо третьи объекты.

WM>>Только этот пункт не запрещает приводить любые лямбды к указателям на функции, он лишь описывает для каких лямбд это приведение будет гарантированно успешным.

NT>

NT>The closure type for a lambda-expression with no lambda-capture


NT>Теперь смотрим на наш код:


NT>
NT>int main()
NT>{
NT>   void (*fp)() = [&]{};
NT>}
NT>


NT>lambda-capture присутствует, однако код компилируется.


Всё верно. Почему он обязан не компилироваться? Приведи цитату, которая это запрещает. Указанный тобой до этого пункт 5.1.2.6 не подходит на эту роль, так как, во-первых, не содержит запрета вообще, а, во-вторых, не применим к данному коду (именно из-за выделенного тобой условия).
Re[4]: lambda to pointer to function conversion
От: Nikita.Trophimov  
Дата: 01.03.13 20:50
Оценка:
WM>Всё верно. Почему он обязан не компилироваться? Приведи цитату, которая это запрещает. Указанный тобой до этого пункт 5.1.2.6 не подходит на эту роль, так как, во-первых, не содержит запрета вообще, а, во-вторых, не применим к данному коду (именно из-за выделенного тобой условия).

Хорошо, давайте мыслить терминами стандарта языка. Итак, мы имеем фразу, разрешающую преобразование лямбды к указателю на функцию в том случае, если лямбда не содержит lambda-capture, а также функция имеет те же параметры и тип возвращаемого значения, как и лямбда. О других возможных преобразованиях ничего не сказано. Любой неописанный стандартом код является ill-formed, однако трансляция не обязана быть закончена, потому что для ill-formed программ требуется лишь выдача diagnostic message. Более того, реализация иметь предоставлять расширения, позволяющие транслировать ill-formed программы.

Но я имел ввиду именно ill-formed код.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.