Я не думаю, что это хорошая идея.Основная проблема, которую я вижу здесь, заключается в том, что использование std::function
почти наверняка предотвратит встраивание, что является весьма важным для производительности алгоритма std ::.Сравните ваш подход с этим .Первый пример - это упрощенная версия вашего кода сверху.Во второй версии я передаю лямбду Transform::compute
напрямую, а не через std::function
.Если вы посмотрите на сгенерированный код, то увидите, что во второй версии компилятор может в основном встроить все.В первой версии, с другой стороны, компилятор не может ничего встроить.Каждая итерация функции вычисления будет выполнять косвенный вызов лямбда-выражения, содержащегося в std::function
.
. Помимо этих проблем с производительностью, мне неясно, что именно представляет собой такой класс Transform
.Он связывает контейнер входных данных с помощью метода std::function
и print()
, что кажется мне совершенно произвольным скоплением несвязанных функциональных возможностей.Концептуально я бы рассматривал преобразование как нечто, что можно применить к некоторым входным данным для получения некоторых выходных данных.Данные, к которым применяется преобразование, кажутся чем-то довольно независимым от самого преобразования.Акт печати вектора на std::cout
тем более.Нет ничего плохого в инкапсуляции определенного вида преобразования в классе.Но я бы сказал, что вы хотите, чтобы экземпляры этого класса Transform
представляли конкретное преобразование, которое затем можно применить к любым заданным входным данным. Например, :
#include <algorithm>
#include <vector>
class MyTransform
{
int max_num;
public:
MyTransform(int max_num = 2) : max_num(max_num) {}
void operator ()(std::vector<int>& data) const
{
std::transform(std::begin(data), std::end(data), std::begin(data), [this](int x)
{
return x > max_num ? max_num : x;
});
}
};
int main() {
std::vector<int> data = {1, 3, 4, 5, 2, 1, 4, 5, 3, 5, 3, 6, 4, 6, 12};
MyTransform f(2);
f(data);
}
Здесь MyTransform
фактически представляет экземпляр вашего примера преобразования (для некоторого параметра max_num
).MyTransform
объекты могут быть переданы и применены к любому данному std::vector<int>
.Или сокращенная версия :
#include <algorithm>
#include <vector>
auto my_transform(int max_num)
{
return [max_num](auto&& data)
{
std::transform(std::begin(data), std::end(data), std::begin(data), [max_num](int x)
{
return x > max_num ? max_num : x;
});
};
}
int main() {
std::vector<int> data = {1, 3, 4, 5, 2, 1, 4, 5, 3, 5, 3, 6, 4, 6, 12};
auto f = my_transform(2);
f(data);
}