Когда я должен std :: пересылать вызов функции?

Фрагмент кода, который я видел в Эффективный Современный C ++ имеет умную реализацию обоснование приборов создать таймер функции :

auto timeFuncInvocation =
[](auto&& func, auto&&... params)
{
start timer;
std::forward<decltype(func)>(func)(
std::forward<decltype(params)>(params)...);
stop timer and record elapsed time;
};

Мой вопрос о std::forward<decltype(func)>(func)(...

  • Насколько я понимаю, мы на самом деле Кастинг функция его оригинал типа, но зачем это нужно? Похоже, что простой вызов поможет.
  • Есть ли другие случаи, когда мы используем совершенную переадресацию для вызова функции?

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

7

Решение

Лучшее описание того, что std::forward<decltype(func)>(func)(...) делает будет сохранение категории значения аргумента, передаваемого в лямбду.

Рассмотрим следующий функтор с ref-qualified operator() Перегрузки.

struct foo
{
void operator()() const &&
{ std::cout << __PRETTY_FUNCTION__ << '\n'; }

void operator()() const &
{ std::cout << __PRETTY_FUNCTION__ << '\n'; }
};

Помните, что в теле лямбды func это значение (потому что у него есть имя). Если вы этого не сделали forward аргумент функции && квалифицированная перегрузка никогда не может быть вызвана. Более того, если & квалифицированная перегрузка отсутствовала, тогда даже если вызывающий абонент передал вам значение foo Например, ваш код не сможет скомпилироваться.

Живая демо

10

Другие решения


По вопросам рекламы [email protected]