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

85
7

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

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

а также

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

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

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

спросил(а) 2019-02-02T14:44:00+03:00 2 года назад
1
Решение
74

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

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

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

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

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

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

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

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

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

ответил(а) 2019-02-02T17:14:00+03:00 2 года назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема