По мотивам беседы в чате по с++:
Проблема
Следующий код не компилируется по причине того, что тип лямбда выражения является уникальным (
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