Код: Выделить всё
#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); }
Тем не менее, 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()
Производственный код фактически оборачивает лямбда-выражение, предоставленное вызывающей стороной ( или вызываемый) в std::function.
Лямбда-выражение вызывающего объекта встроено. Тем не менее, я не могу найти способ исключить цикл для обычного варианта использования с одним вызовом без определения двух отдельных лямбда-функций.
Подробнее здесь: https://stackoverflow.com/questions/793 ... -my-lambda
Мобильная версия