LINUX.ORG.RU

C++ lambda expressions

 ,


0

3

Читаю Страуструпа 2013 года. На одной странице, посвящённой lambdas, целый ворох вопросов:

1)

If a lambda expression does not take any arguments, the argument list can be omitted

Тем не менее, при использовании лямбд с auto указывать () нужно если есть явный возвращаемый тип ->:

auto z = [] -> int { return 1; };

main.cpp:24: ошибка: expected '{' before '->' token
auto z = [] -> int { return 1; };
^



Если -> нет, то ошибок компиляции нет. Почему гуру не пишет об этом?

2)

[=, capture-list]: implicitly capture by value all local variables with names not mentioned in
the list. The capture list cannot contain this. The listed names must be preceded by &



Тем не менее, сам Страуструп неоднократно пишет вот так:

auto z2 = [=,y]{ if (y) return 1; else return 2; }

Почему гуру сам нарушает «must»?

3)

double (∗p3)(int) = [](int a) { return sqrt(a); }; // error : argument types do not match

Почему argument types do not match?

★★★

Последнее исправление: former_anonymous (всего исправлений: 2)

Почему argument types do not match?

std::sqrt(int) скорее всего превратится в float. Поэтому у тебя float (*p3)(int) должно быть, попробуй.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от former_anonymous

Там где-то double должен быть по идее, наверное опечатка.

asaw ★★★★★
()

Если -> нет, то ошибок компиляции нет. Почему гуру не пишет об этом?

Видимо, об этом написано дальше в качестве уточнения.

Почему гуру сам нарушает «must»?

Полный текст же наверное такой:

The listed names must be preceded by & to be captured by reference.

Почему argument types do not match?

Может имелось в виду различие в аргументах лямбды и sqrt. «error» не всегда значит ошибку компиляции, тут может быть логической ошибкой.

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Полный текст же наверное такой:
The listed names must be preceded by & to be captured by reference

нет:

[=, capture-list]: implicitly capture by value all local variables with names not mentioned in
the list. The capture list cannot contain this. The listed names must be preceded by &. Variables named in the capture list are captured by reference.



тут может быть логической ошибкой

тут нет логической ошибки, т.к. sqrt в C++11 имеет перегрузки для integral types, включая int, не говоря уже о возможности implicit conversion из int в double:

double sqrt (T x);

Additional overloads are provided in this header (<cmath>) for the integral types: These overloads effectively cast x to a double before calculations (defined for T being any integral type)

former_anonymous ★★★
() автор топика
Последнее исправление: former_anonymous (всего исправлений: 1)
Ответ на: комментарий от former_anonymous

The listed names must be preceded by &. Variables named in the capture list are captured by reference.

Возможно неудачная формулировка. Ну и если отсутствие & не приводит к ill-formed коду, то может для ясности пишет так.

тут нет логической ошибки, т.к. sqrt в C++11 имеет перегрузки для integral types, включая int, не говоря уже о возможности implicit conversion из int в double:

«Ошибка» может быть в том, что тип аргумента лямбды не double и будет нежелательное округление.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 2)

auto z = [] -> int { return 1; };

auto z = [] { return 1; };

andreyu ★★★★★
()

double (∗p3)(int) = [](int a) { return sqrt(a); }; // error : argument types do not match

#include <cmath>
double (∗p3)(int) = [](int a) { return sqrt(a); };

andreyu ★★★★★
()
Ответ на: комментарий от xaizek

Возможно неудачная формулировка

это не то чтобы неудачная, а совсем неправильная. Во-первых, он написал, что аргументы должны быть обрамлены & (не должны), и то что аргументы захватываются по ссылке (могут и нет как следствие от предыдущего).

«Ошибка» может быть в том, что тип аргумента лямбды не double и будет нежелательное округление.

не понял, в каком именно выражении будет округление?

former_anonymous ★★★
() автор топика
Ответ на: комментарий от former_anonymous

Во-первых, он написал, что аргументы должны быть обрамлены & (не должны), и то что аргументы захватываются по ссылке (могут и нет как следствие от предыдущего).

«must» это не «have to» и является в том числе и настоятельной рекомендацией, а учитывая, что Страуструп не native English speaker, мог и ошибиться в выражении (редакторы и не такое пропускают).

не понял, в каком именно выражении будет округление?

При вызове лямбды double обрежется до int (p3(10.5)).

В целом никакого дополнительного смысла в том как написано нет, можно просто продолжать читать.

xaizek ★★★★★
()
Ответ на: комментарий от former_anonymous

я не умею читать мысли из С++ кода.

На код во втором квотировании моего поста компилятор не ругался.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

у меня тоже, вопрос почему гуру пишет, что в этом коде error

former_anonymous ★★★
() автор топика
Ответ на: комментарий от xaizek

«must» это не «have to» и является в том числе и настоятельной рекомендацией

Я всегда думал, что should - настоятельная рекомендация.

Dudraug ★★★★★
()
Ответ на: комментарий от former_anonymous

Не может оно быть наоборот, они очень близки, почти синонимичны. Но «have to» более формальный (подходит к стандарту языка больше, как мне кажется), а must больше основан на мнении. Правда на письме «have to» на must заменять могут.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от Dudraug

should слабее их обоих и больше как совет.

xaizek ★★★★★
()

If a lambda expression does not take any arguments, the argument list can be omitted

Тем не менее, при использовании лямбд с auto указывать () нужно если есть явный возвращаемый тип ->:

Да, и про это написано парой строк ниже.

When the suffix return type notation is used, we cannot omit the argument list.

utf8nowhere ★★★
()

Если ты хочешь найти книгу по C++, в которой описана каждая интересующая тебя деталь, то их нет. Кроме стандарта, конечно. Но там ничего нет про реализацию в компиляторах.

Kuzy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.