[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) . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.