Почему компиляторы не встраивают константы в мою лямбду?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему компиляторы не встраивают константы в мою лямбду?

Сообщение Anonymous »

Учитывая определение:

Код: Выделить всё

#include 

void call();

static constexpr inline auto nWrap(std::size_t n) {
return [n]() constexpr { for (std::size_t i = 0; i != n; ++i) call(); };
}

std::function oneCall() { return nWrap(1); }
std::function nCalls(std::size_t n) { return nWrap(n); }
Я ожидал, что oneCall от оптимизирующих компиляторов вернет функционал с развернутым/устраненным циклом.
Тем не менее, gcc, clang, msvc и icc создают определения функций с циклами:

Код: Выделить всё

.L3:
call    call()
addq    $1, %rbx
cmpq    0(%rbp), %rbx
jne     .L3
На самом деле, никакие выражения, включающие захваченные константы (например, сумму двух констант), не являются встроенными. Есть ли в определении что-то, препятствующее встраиванию? (Поскольку все компиляторы, похоже, с этим согласны.)
Как я могу определить nWrap, чтобы вызывающая сторона могла встроить захваченные константы? (т. е. развернуть цикл, если он вызван с константой времени компиляции n)
Перенос определения лямбды вручную в oneCall действительно устраняет цикл в сгенерированном код:

Код: Выделить всё

constexpr const std::size_t n = 1;
return [n] { for (std::size_t i = 0; i != n; ++i) call(); };

Код: Выделить всё

std::_Function_handler::_M_invoke(std::_Any_data const&):
jmp     call()
Шаблон nWrap этого не делает, кроме случая, когда я использую параметр шаблона для n. Добавление или удаление различных статических, встроенных и constexpr малоэффективно.
Производственный код фактически оборачивает лямбда-выражение, предоставленное вызывающей стороной ( или вызываемый) в std::function.
Лямбда-выражение вызывающего объекта встроено. Тем не менее, я не могу найти способ исключить цикл для обычного варианта использования с одним вызовом без определения двух отдельных лямбда-функций.

Подробнее здесь: https://stackoverflow.com/questions/793 ... -my-lambda
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»