[FYI] Применение унарного плюса к лямбда выражению без захва
От: Анатолий Широков СССР  
Дата: 01.07.17 09:19
Оценка: 57 (8) :))) :)))
По мотивам беседы в чате по с++:

Проблема

Следующий код не компилируется по причине того, что тип лямбда выражения является уникальным (5.1.2.3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below.):

#include <initializer_list>
int main() {
   int s = 0;
   for(auto f : {[]{return 1;}, []{return 2;}}) {
         s += f();
   }
   return 0;
}


prog.cpp: In function ‘int main()’: prog.cpp:5:46: error: unable to deduce ‘std::initializer_list<auto>&&’ from ‘{<lambda closure object>main()::<lambda()>{}, <lambda closure object>main()::<lambda()>{}}’ for(auto f : {[]{return 1;}, []{return 2;}}) { ^ prog.cpp:5:46: note: deduced conflicting types for parameter ‘auto’ (‘main()::<lambda()>’ and ‘main()::<lambda()>’)


Решение

Но лямбда выражение без захвата может быть приведено к указателю на функцию (5.1.2.6 The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual nonexplicit const conversion function to pointer to function with C++ language linkage (7.5) having the same parameter and return types as the closure type’s function call operator.), а унарный плюс может быть применен к указателю (5.3.1.7 The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument.) Следовательно, применение унарного плюса к лямбда выражению должно привести его к указателю на функцию:

#include <initializer_list>
int main() {
   int s = 0;
   for(auto f : {+[]{return 1;}, +[]{return 2;}}) {
         s += f();
   }
   return 0;
}


Компилируется gcc, clang, но, к сожалению, не компилируется vs 2015, 2017.

p.s. Все отсылки были к драфту стандарта http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4640.pdf
Отредактировано 03.07.2017 9:34 Анатолий Широков (fixed typo) . Предыдущая версия .
Re[2]: [FYI] Применение унарного плюса к лямбда выражению без захвата
От: Muxa  
Дата: 01.07.17 13:53
Оценка: +5 :))) :))) :))
Re: [FYI] Применение унарного плюса к лямбда выражению без захвата
От: T4r4sB Россия  
Дата: 01.07.17 10:25
Оценка: +2 :)
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: [FYI] Применение унарного плюса к лямбда выражению без захва
От: prezident.mira Россия  
Дата: 04.07.17 14:24
Оценка: :))
АШ> не компилируется vs 2015, 2017.

А этими кривыми поделками кто-то пользуется?!
Re: [FYI] Применение унарного плюса к лямбда выражению без захва
От: Mr.Delphist  
Дата: 04.07.17 10:37
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>По мотивам беседы в чате по с++:


АШ>Проблема


АШ>Следующий код не компилируется по причине того, что тип лямбда выражения является уникальным (5.1.2.3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below.):


В порядке идеи: а если в std::function эти штуки обернуть, не поможет? Сбацать вектор функций, по нему итерироваться.

Хотя в целом лямбды в плюсах всё ещё оставляют впечатление полуфабриката, это да.
Re[2]: [FYI] Применение унарного плюса к лямбда выражению без захва
От: Анатолий Широков СССР  
Дата: 04.07.17 11:13
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>В порядке идеи: а если в std::function эти штуки обернуть, не поможет? Сбацать вектор функций, по нему итерироваться.


MD>Хотя в целом лямбды в плюсах всё ещё оставляют впечатление полуфабриката, это да.


Конечно, можно и std::vector<std::function<int()>>, и даже не прибегая ни к vector, ни к function:

int (*f[])() = {[]{return 1;}, []{return 2;} };


но хотелось заинлайнить через initializer_list.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.