2015-09-21 6 views
2

Я нашел функцию, определенную таким образом на:
http://en.cppreference.com/w/cpp/language/decltypeОбъявление функции с использованием авто, decltype, = []

Я никогда не видел этот синтаксис, используемый для определенной функции, может кто-нибудь объяснить это?
Это только кажется, работать с авто и decltype

#include <iostream> 
using namespace std; 

auto f = [](int a, int b)->int 
{ 
    return a * b; 
}; 

/* 
int f = [](int a, int b) //DOES NOT WORK 
{ 
    return a * b; 
}; 
*/ 

int main() 
{ 
    int a = 2, b = 3; 
    cout<<f(a,b); 
    return 0; 
} 

Я не уверен, если следующая функция использует dectype, когда мы делаем:

->int  

Если да, то каким образом?

+3

'f' нет функции, но лямбда –

+1

HTTP: //en.cppreference. com/w/cpp/language/lambda Не уверен, что вы спрашиваете о 'decltype' – Praetorian

+2

@Freddy' trailing return type', фактически ..;) – JSQuareD

ответ

3
auto f = [](int a, int b)->int 
{ 
    return a * b; 
}; 

f здесь глобальная переменная некоторого анонимного типа, держа экземпляр анонимного объекта функции, определенной после operator=. Такие анонимные функции объекты называются лямбда с, они могут произойти везде, где вы можете иметь некоторое выражение:

int main(int, char**) { 
    ([](int a) { 
    cout << "lambda called with " << a << endl; 
    })(42); 
    return ([](int a, int b) { return a - 2 * b; })(42, 21); 
} 

Общий синтаксис такого лямбда-выражения заключается в следующем:

"["CAPTURE"]" PARAMETERS ["mutable"] [RETURN] { BODY } 

CAPTURE быть список нулевой руды больше

  • переменная из охватывающей области, захват по значению
  • переменные из области видимости, предшествует &, захват путем ссылкой
  • & средства захватить все переменные из области видимости по ссылке
  • = средства захватить все переменные из области видимости по значению

PARAMETERS являются обычными списками параметров, которые вы знаете из функций, необязательно (начиная с C++ 14) с auto и выводите тип.

mutable позволяет лямбда изменять свои захваченные переменные.

факсRETURN содержит спецификацию типа возврата, например. -> void и BODY содержит произвольные выражения и выражения.

Примечание что это всего лишь приблизительный эскиз синтаксиса, но он должен вас начать. Вы можете узнать больше о lambdas в стандарте, ищите «C++ 11 lambda» в Google или, например, here.

Btw, лямбда ничего привидение, вы не можете думать о ваших f как грубый эквивалент следующего, "старый стиль" C++ код:

struct { 
    int operator()(int a, int b) const { 
    return a * b; 
    } 
} f; 
+0

Скобки вокруг лямбда не нужны и на самом деле не добавляют ясности выражения. '[] (int a) { cout <<" лямбда называется "<< a << endl; } (42); 'адекватен. – Adrian

+1

Я знаю, я поставил их там, чтобы совершенно ясно, где заканчивается определение лямбда и где начинается фактический вызов лямбда. –

2

При использовании:

auto f = [](int a, int b)->int 
{ 
    return a * b; 
}; 

Тип f - тип выражения лямбда. Это не int, возвращаемый тип выражения лямбда.

Что касается части -> int, это единственный синтаксис, доступный для явного указания типа возврата выражения лямбда. Это то, что опущено, возвращаемый тип выводится компилятором с использованием алгоритма, указанного в стандарте:

5.1.2 лямбда-выражений

4 Если лямбда-выражение не включают lambda-declarator, это как будто лямбда-декларатор были(). Если лямбда-выражение не включает в себя замыкающий обратный типа, это как если трейлинг-возвратного типа обозначает следующий тип:

- если соединение-заявление является формы
{атрибут-спецификатор-seqoptreturnвыражение; }

тип-го e возвращаемое выражение после преобразования lvalue-to-rvalue (4.1), преобразование от массива к указателю (4.2) и преобразования функции в указатель (4.3);

- в противном случае, пусто.

[Пример:

auto x1 = [](int i){ return i; }; // OK: return type is int 
auto x2 = []{ return { 1, 2 }; }; // error: the return type is void (a 
// braced-init-list is not an expression) 

- конец пример]

Смежные вопросы