for_each_arg: Вызов функции для каждого аргумента функции
Вольный перевод статьи .
Как вызвать функцию для каждого аргумента другой функции?
Например, у нас есть функция
и мы хотим применить некую функцию f к каждому аргументу функции g.
Требуется некий for_each_arg, который позволит выполнить следующее:
Как это решить с компилятором, не поддерживающим C++17?
Используем std::initializer_list, в список аргументов которого будем передавать результаты вызовов
f c аргументами args:
std::initializer_list<?>{(f(args))...}
Возникают проблемы:
1) Не знаем rvalue или lvalue передается в args - используем std::forward.
2) Какого типа элементы содержит std::initializer_list<?> . Допустим, что int, но функция f не обязана возвращать int,
3) поэтому приведем её возвращаемое значение к void и объединим оператором "запятая" с целым 0.
В результате имеем:
Ну а с С++17 всё гораздо проще:
Как вызвать функцию для каждого аргумента другой функции?
Например, у нас есть функция
template<typename... Args>
void g(Args&&... args)
{
// ...
}
и мы хотим применить некую функцию f к каждому аргументу функции g.
Требуется некий for_each_arg, который позволит выполнить следующее:
template<typename... Args>
void g(Args&&... args)
{
for_each_arg(f, args...);
}Как это решить с компилятором, не поддерживающим C++17?
Используем std::initializer_list, в список аргументов которого будем передавать результаты вызовов
f c аргументами args:
std::initializer_list<?>{(f(args))...}
Возникают проблемы:
1) Не знаем rvalue или lvalue передается в args - используем std::forward.
2) Какого типа элементы содержит std::initializer_list<?> . Допустим, что int, но функция f не обязана возвращать int,
3) поэтому приведем её возвращаемое значение к void и объединим оператором "запятая" с целым 0.
В результате имеем:
template<class F, class...Args>
F for_each_arg(F f, Args&&...args) {
std::initializer_list<int>{((void)f(std::forward<Args>(args)), 0)...};
return f;
}
Ну а с С++17 всё гораздо проще:
template<class F, class...Args>
F for_each_arg(F f, Args&&...args) {
(f(std::forward<Args>(args)),...);
return f;
}
Комментарии
Отправить комментарий