В чем разница между встроенной и неконтролируемой лямбда-захватом в заголовке? - PullRequest
0 голосов
/ 02 февраля 2019

Если я объявляю лямбда без захвата в заголовке, в чем разница между

inline auto myLambda = []() { ... };

и

constexpr auto myLambda = []() { ... };

Если я правильно понимаю, constexpr подразумевает inline и лямбдыявляются constexpr по умолчанию.Так что я даже не уверен, что мне нужно ключевое слово inline или constexpr.

Чего я хочу избежать, объявив myLambda inline нарушением правила одного определения (ODR), поскольку эта переменная сбыть видимым в нескольких единицах перевода.

1 Ответ

0 голосов
/ 02 февраля 2019

Если я правильно понимаю, constexpr подразумевает inline, и лямбды по умолчанию constexpr.

Первая часть верна, но не для этого случая.From [dcl.constexpr] / 1 :

Функция или член статических данных, объявленные с помощью спецификатора constexpr или consteval, неявно являются встроенной функцией или переменной ([dcl.inline]).

В нашем случае у нас нет ни функции, ни статического члена данных, поэтому он не является встроенным.Вы должны были бы явно пометить его как таковой.

Вторая часть не совсем правильна.From [expr.prim.lambda.closure] / 4 :

Оператор вызова функции или любая конкретная специализация шаблона оператора является функцией constexpr, если соответствующая лямбда-expression * s параметр-объявление-предложение сопровождается constexpr или consteval, или оно удовлетворяет требованиям для функции constexpr ([dcl.constexpr]).

Оператор вызова по умолчанию constexpr, а сама лямбда - нет.Что для лямбды без захвата в основном хорошо, вы все равно можете использовать оператор вызова - как показано в примере для этого раздела:

auto ID = [](auto a) { return a; };
static_assert(ID(3) == 3);                      // OK

Короче говоря, если выобъявляя эту лямбду в заголовке, вам определенно нужно ключевое слово inline, и не помешает просто щелкнуть по ключевому слову constexpr.

...